[Richard Suchenwirth] 2002-04-28 - Here is an attempt to model deferred evaluation with traces: three lines of code exercise all subcommands of the [trace] command. First a previous trace is checked and possibly deleted, then the new one registered. The idea is that a variable is "bound to" a "body" which is executed when the variable value is retrieved, so references to other variables are re-evaluated, and changes to them reflected accordingly. Example: set a {1 2} set b {3 4} willset c {list $a $b} => {1 2} {3 4} set b {30 4} set c => {1 2} {30 4} proc willset {varName body} { set trace [uplevel 1 trace vinfo $varName] ;# have previous? if {$trace != ""} {uplevel 1 eval trace vdelete $varName $trace} uplevel 1 [list trace var $varName r "set $varName \[$body\];#"] uplevel 1 [list set $varName] } ---- As shown above, deferred assignment with ''willset'' easily passes the test given by [davidw] in [linked lists]. His added requirement for garbage collection does not seem to be an issue - the trace to an ''willset'' variable is automatically deleted when the variable ceases to exist. As shown by [Arjen Marcus] before, linked lists and whatever references may be good for can be implemented in Tcl. It's just that Tcl references are not "physical" pointers, but (as usual) strings: variable names, which are mapped to physical pointers in an internal hash table. The problem of "dangling references" (stored references to objects that do no more exist) is likewise there, but if it occurs, it is rather clearly reported and does not lead to a segmentation fault: % set a [list 1 2] % set b [list 3 4] % willset c {list $a $b} {1 2} {3 4} % set b [list 30 4] 30 4 % set c {1 2} {30 4} % unset a % set c can't read "c": can't read "a": no such variable Introspection was not explicitly coded: find out what body is tied to a variable with trace vinfo c Mixing eager assignment (with [set]) and lazy assignment (with ''willset'') currently has the troublesome property that the [set] returns the new value, but later accesses still fire the trace: % set c hello => hello % set c {1 2 30 4} Obviously, this isn't a finished solution yet... the following write trace didn't work out: #set writetrace "trace vdelete $varName \[trace vinfo $varName\];#" #uplevel 1 trace var $varName w $writetrace Maybe raising an error is enough for the write trace. Come to think, ''willset'' suddenly resembles ''dynavar'' from [Braintwisters]! ---- [Arts and crafts of Tcl-Tk programming]