Re: Array defaults vs exception overhead

"Alexandre Ferrieux" <alexandre.ferrieux@xxxxxxxxx> wrote in message

The following idiom happens often in my code:

if {[info exists a($x)]} {do_something $a($x)}

Problem: the above does the hash lookup twice. Argh.
A natural answer is:

catch {do_something $a($x)}

But unfortunately, this is even slower (from 7.6 to 8.4.14) due to the
exception unwinding overhead.
It sort of depends on what percentage of time you expect the array slot
to be undefined. If slot is usually defined then the catch is overall less
otherwise info exist wins.
I have also long wished for a more concise solution to this situation. But
speed is usually not an issue as [info exists] is really quite fast. Still
end up coding the array reference twice which can be annoying when
the index is built of 3 or 4 substrings. Sometimes I use a macro to
automatically test and fetch in one call.

I wonder, does the Tcl interp "cache" array lookups so that immediately
following identical look ups are faster? Doubtful.

Moreover, it is not strictly equivalent since it loses any exception
from [do_something].
To restore equivalence, we'd need pattern matching on the error...
even slower !

Any better idiom doing just one hash lookup ?

Another approach would be to have "array defaults": an option to
substitute a common value to all undefined slots of an array instead
of raising an exception. This one would also allow things like a blind
"incr a($x)".
I remember an old discussion on this. What's the current status ?

Re incr, that issue is addressed in 8.5 (it auto creates the variable).
I can't see "array defaults" going anywhere, but who knows.

My thought (all of 10 seconds):
info value a(x) defaultValue
Could have info exists baked-in and if non-existent,
just return the supplied default otherwise return the
wanted value.

Yet another approach would be more general, and akin to a Bourne Shell
mechanism: "variable defaults".
The idea is to have ${foo:-bar} yield $foo or bar if foo is undefined.
The natural extension to arrays yields

do_something ${a($x):-nope}
Interesting. However I'd don't think I'd enjoy reading Tcl Core comments on
a TIP of this sort :^(


(here [do_something] is supposed to handle 'nope' innocuously, at
least faster than a 2nd hash lookup)

Reactions ?