Version 1 of Backquoting

Updated 2001-11-29 10:03:09

Comparing Tcl and LISP, I see the following differences:

  • In LISP, normally all atoms are evaluated, variables to their value; so FOO in LISP would amount to $foo on Tcl
  • In LISP, lists or atoms may be quoted( (QUOTE FOO) or 'FOO) to prevent the evaluation; in Tcl, this is curlies around a list, and no special markup for whitespace-less words
  • In a quoted list, it is possible to still evaluate some elements:
 '(NOT THIS BUT ,THAT)

where the leading comma ("backquote") triggers the evaluation of THAT, while leaving the other elements quoted.

Tcl's syntax does not prepare for this case, but as usual it's possible to implement it oneself:

 set template {
   a list with $signs, [brackets] which the parser shall not see,
   and @that@ also
 }
 regsub -all @that@ $template "simulated backquote" template

The @-signs are not Tcl syntax, we picked them ourselves, and surrounding the backquotable element on both sides is more robust if either one bq name is prefix to another (e.g. @dir@ and @dirlist@), or @ signs occur in the text that are not supposed to be substituted.

This technique is useful in generating code, where long text blocks with Tcl-parser-relevant characters shall be left untouched, while parts must still be substituted. For usage examples, see for instance Gadgets or Pipe Servers in C from Tcl.


With new Tcl's (8.3.3 and up?), there's also string map as alternative for regsub:

    set template [string map [list @that@ "simulated backquote"] template"

Might seem longer (don't know about speed), but it returns the result inline, allowing you to do things like (I prefer "#"):

  proc foo {bar} [string map [list #A $a #B $b] {
    if {#A} { puts Yeay! } else { #B }
  }]

Same can be done with format, but given the way its args are ordered, string map seems more readable (well, to JCW, anyway).


Arts and crafts of Tcl-Tk programming