The following code fragment if {$x0 > [lindex $description 1]} { set x0 [lindex $description 1] } if {$x0 < 0} { set x0 0 } is typical Tcl: dollars, brackets, braces, assignments with set. Any Tcl novice will understand it within seconds. And still, after looking at it again, I felt a slightly salty taste, like of sweat (or tears). Such adjusting a variable to upper/lower bounds occurs frequently and could be factored out to a proc - once defined, each call would save 5 out of 6 lines of source code. When designing the (trivial) proc, I experimented with the "API look and feel", and finally wrote this: proc limit {_var "between" lower "and" upper} { upvar $_var var if {$var > $upper} { set var $upper } elseif {$var < $lower} { set var $lower } return $var } The argument list may look surprising. It reads quite natural, but the "parameters" ''between'' and ''and'' are never used. They are just "syntactical sugar" thrown into the arg list (that I marked them with quotes is another sugar that's irrelevant for Tcl, but helpful for the reader), so you can call the proc like limit x0 to 0 .. 1024 After reading this non-pseudocode myself, I thought it kind of sweet, and even more so when I imagined how other people would feel reading this in sources which they did not write but tried to understand. (-: Our software is often self-documenting, because nobody else does it, but this executable code comes close to a good comment :-) '''The cost of sugar''': Everything has its price. Sugar arguments cost some extra time (about 24 microseconds per call in this case) and some extra bytes in memory. But they might still be worth it - if they save some seconds to people reading code, and maybe even give them a good taste in the mouth. Cf. [upvar sugar], [Steps towards functional programming] -- [Richard Suchenwirth] ---- '''args sugar''': When you collect a varying number of arguments with the args variable, and unpack them with the foreach {x y z} $args {break} construct, remaining arguments are discarded. This means you can add sort of comments in the call, see [A set of Set operations]: if [Set $S has "white" as element] {... ''args'' also helps to save curly braces, e.g. if you don't want to talk to Tcl like to a dog, proc please {args} {uplevel catch [list $args]} please close $f ---- '''Cheap sugar''': If you find yourself typing "expr" more often than you like, give it an alias (thanks to Jeff Hobbs for the tip!) like interp alias {} = {} expr Looks, and does, magic: now expr is also reachable by the equal sign: set a [= $b+$c] (yes, I know about expr{}, and sometimes care ;-) '''RS''' Even cheaper (=free) are fancy variable names, e.g. when using regexp to extract substrings from a string: regexp -nocase {subject: ?(.*)} $header -> subject A variable named "->" is assigned the whole matchstring, which we usually are not interested in. Looks good, costs nothing. ---- '''List access sugar:''' One Perlist once complained on comp.lang.tcl that accessing lists was so clumsy in Tcl, having to say set i [lindex $j 0] for, as they'd say in Perl, $i = $j[0]; If you feel the same, you can say proc $ {_L n} {upvar $_L L; lindex L $i} set i [$ j 0] Dollar is a legal proc name, if not followed by A-Za-z0-9_. A more elaborate version allows call by name or by value for a single element or a slice: proc $ {_L from {to {}}} { if {$to=={}} {set to $from} if [uplevel "info exists [list $_L]"] { upvar $_L L } else { set L $_L} lrange $L $from $to } so you can say set list {1 2 3 4 5} set i [$ list 1] ==> 2 set i [$ list 3 end] ==> {4 5} set i [$ {a b c d e f g} 2 4] ==> {c d e} Watch out for the space after the dollar, though. -- ''RS'' ---- '''Predicate sugar''': see [Predicates: on being and having] on how to wrap one-argument and element predicates into pretty natural English, like if {[is array A] && [has A 4711]} {...} ---- '''Version sugar''': Having defined the slightly ugly proc version {"of" pkg op vers} { expr [package vcompare [package provide $pkg] $vers] $op 0 } you can further on write (cf. [Unicode file reader]) the beautiful if [version of Tcl >= 8.1] {... BTW: In other languages, this won't be any sweet ;-) ''RS'' version("of","Python",">=","8.1") ---- '''Whitespace sugar''': Here's a trivial algorithm for reading a text file to a list, but note the "whitespace sugar": mentions of a variable are vertically aligned to indicate data flow ;-) proc file:lines {fn} { set f [open $fn r] set t [read $f [file size $fn]] close $f split $t \n } ;#RS ---- '''Either sugar''': Here's a lightweight ''try'' that makes catches, ''info exist'' or other routine tests look more pleasing: proc either {body1 "or" body2} { if {[catch {uplevel $body1} t]||$t==""} {uplevel $body2} } # e.g.: either {set x $y} or {set x 0} ''KBK'' (10 January 2001) -- Watch out for [[break]], [[continue]] and [[return]] in ''body1'' and ''body2''. A production-grade implementation of ''either'' would adapt the code from [try ... finally ...], which handles anything but the problematic [[return -code]]. ---- [Arts and crafts of Tcl-Tk programming]