An essay on Tcl dereferencing

Many Tcl newcomers ask
How do I write '$$myvariable' in Tcl?
often under the influence of Perl, where this double dereferencing is a standard, if deprecated, part of the syntax (my big question: why does all of PHPdom remain infatuated by the construct?).

The answer they most want is, [set $myvariable], as in

        puts myvariable a
	set a 13
	puts "The value is [set $myvariable]."
Joe Moss explains this in detail. Note that there are other ways to achieve the same, with tricky upvar-ing, multiple evaluations as in eval puts "The value is \$$myvariable." and puts "The value is [subst $$myvariable].", and so on.

In almost all instances, though, this search for a double dereferencing should be taken as an opportunity to use an associative array to engineer the algorithm more readably. If you find yourself writing code of the style

       foreach variable {firstname middlename lastname} {
	 set $variable [string toupper [set $variable]]
       }
     
consider redoing it as the more idiomatic
	 # "name" here will take on values "first", "middle", "last".
       foreach name [array names personname] {
	 set personname($name) [string toupper $personname($name)]
       }
     
Introspective tasks, such as construction of a debugging facility, certainly require explicit double de-referencing. For most applications, though, an associative array is the right approach. Double indirection usually shows good sense [ref], in that it's a sign the programmer is working toward a higher abstraction. The confusion in this area simply has to do with what is idiomatic in Tcl. Associative arrays consistently offer a useful abstraction that's usually appropriate for such automation across the text of a script.

There's another aspect of dereferencing that deserves mention here. Not only associative arrays, but even Tcl's $ is "mere" syntactic sugar. There is no intrinsic need for variable substitution with $ in Tcl. Substition of command values is sufficient, for one can always code in the style of

	set first Washington
	set second Adams
	puts "The two values are [set first] and [set second]."
     
Very early versions of Tcl lacked $ syntax. Brent Welch [ref] delights in remembering that John [ref] wondered "if it should be 'added'."

Thinking about Tcl this way emphasizes the language's similarities with LISP and Forth, rather than Perl and sh(ell). To do so would be sub-optimal for reaching the mass audiences that use Tcl, or as Brent answered John at the time, "it would be pretty clunky to write [set x] every time you needed a variable's value." It is interesting, none the less, to consider how simple the Tcl core syntax [give ref] becomes with only a single substitution rule, and how functional [give ref] a style Tcl can support. While Tcl certainly is procedural [...], it has no privileged notion of assignment; set is just another command.

For more details, see the Tcl-ers' Wiki references on related subjects.


Cameron Laird's essay on Tcl dereferencing/claird@phaseit.net