This page is intended as to summarize some coding pitfalls I encountered in my early days of Tcl programming. As far as I know, this has not been issued anywhere else. Further contributions welcome -- RJM.
While coding, it is important to realize which type of argument is expected by the various Tcl commands. This saves unnecessary quotings or even erroneous quotings. Also superfluous commands could be entered as in this example:
if [expr {$a < 0}] {set a 0}
Such silly sort of code lines may well occur when a beginner is getting confused about using the proper quoting, or when one thinks that only simple comparisons are allowed with if { } *.
The more appropriate method of writing the above is
if {$a < 0} {set a 0} ;# the first 'if' argument already expects an expression
While the original line may be valid Tcl code, it is not one of the Tcl best practices. This is the importance of learning Tcl idioms and having a collection of good Tcl examples from which to learn.
To show a possible source of confusion, two commands are compared here:
if {[command...] == xx} { for {[command...]} {..} {
(The curly braces may be omitted in the second example because the enclosed text is one word).
For a confused beginner, both lines seem to conform to a consistent syntax. Of course, the second case yields an error when the nested script does not return a valid command name. The beginner who is reading this should know that:
The first statement can be explained with a reference to little language. The latter statement will be looked at here briefly.
The beginner must realize that the term "necessary" in the second example is incorrect. It suggests that where a command is expected, a []-quoting would be harmless doubling. It must be emphasized that [] does substitution just as $ also substitution. To be precise: [] is not "quoting". See also An Introduction to Tcl Scripting.
Further examples:
A bit confusing for beginners is the use of list in -command options of Tk widgets or as the script argument of bind. The usage of [list .....] in [] results in immediate command subsitution. Its result is treated as the effective command/script for the -command option or binding. It's all in the "Division of Responsibility" Parser <-> Command: Any substitution is carried out during Parsing.
* I have queried my sources for the character sequences if [expr and if {[expr. Indeed I used it when more complex expressions were defined. During this query, I surprisingly found these character sequences in several other sources, too. This includes the activestate distribution (mainly the second character sequence). I'd encourage the reader to check his/her own sources, too. -- RJM
RS: Note that the example above,
if {$a < 0} {set a 0}
could also be written in expr's little language:
set a [expr {$a<0? 0: $a}]
Matter of taste, of course.