dbohdan 2015-02-20: This little hack implements a piece of syntax resembling the expr shorthand from Jim Tcl in Tcl 8.x: $(...). It does so by tracing array reads from the array with the name {} (an empty string).
A kind of double substitution is sadly unavoidable here. Basically, subst is performed on an array index before it is passed to the proc tracing it. This, together with the very syntax used for array indexing, means that you have to manually escape $, and () with a backslash in your expressions. This is rather error prone, which is why the author would recommend against using arrexpr for anything but amusement.
namespace eval ::arrexpr { namespace export * upvar #0 {} {} set () {} trace add variable {} {array read write unset} ::arrexpr::tracer } proc ::arrexpr::tracer {name index op} { if {$name eq ""} { global $name switch -exact -- $op { read { array unset $name * set ($index) [uplevel 1 [list expr $index]] } write { error "not writable" } } } } proc ::arrexpr::use {} { uplevel 1 { upvar #0 {} {} } }
source arrexpr.tcl puts $(2 + 2) proc vector-length {a b} { ::arrexpr::use return $(sqrt\($a * $a + $b * $b\)) } puts [vector-length 1 1] puts $("hello") # Double substitution. :-( set a 1 set b a puts $($$b) ;# prints "1" set value 5 puts $(\$value > 0 ? "positive" : "zero or negative")