It looks like this has something to do with the way TCL is trying to interpret your array call within the expr command context. You might try either adding some quotes or brackets around the actual array call itself, or perhaps setting a local variable to the value of the array call before comparing the values with expr.
set tempVal [$::spammers($clientip)]
if { $::blocktime > [expr { $now - $tempVal } ] } {
Something like that, perhaps. The syntax you're using looks correct, and the data is obviously there if it's passing the if exists call, so it's got to be an interpreter oddity within the expr command string itself.
Colin
Colin