Version 35 of Tcl in comparison

Updated 2006-09-08 16:09:00

Richard Suchenwirth 2002-12-16 - For people experienced in other languages, it may be interesting to compare code snippets between Tcl and other languages, to demonstrate similarities and differences. Please add more from your experience!

C

 void countdown(int n) {         | proc countdown {n} {
    int i;                       |
    for(i=n; i>0; i--) {         |    for {set i $n} {$i>0} {incr i -1} {
       printf("%d...\n", i);     |        puts $i...
    }                            |    }
 }                               | }

My alternative loop shows the relation between For and While:

    void countdown(int n) {        proc countdown {n} {                      subroutine countdown (i)
      while (n>0) {                      while {$n>0} {                         do
         printf("%d...\n", i);              puts $n...                              write (*,*) n
         n--;                              incr n -1                                n=n-1
      }                              }                                            while (n>0)
  }                              }                                            endsubroutine

The main difference is that a FORTRAN while loop is executed at least once; a for loop can terminate before entry.

C /* The above could be: */

 void countdown(int n) {
    for (; n>0; n--)
       printf("%d...\n",n);
 }

slebetman: which has an equivalent Tcl construct:

 proc countdown {n} {
    for {} {$n>0} {incr n -1} {
        puts $n
    }
 }
  • Everything is a command in Tcl. Function definitions are done with the proc command, assignments with the set command, in/decrementation of integers with the incr command.
  • Retrieving the value of a variable goes with prefixed $ sign - while mentioning the name of a variable it is not used
  • Variable type rarely matters and is not declared. Only incr would complain if its first argument is not an integer (MG Well, there isn't really "variable type" - everything is a string. incr just expects a var to be set to a string that looks like an integer...)
  • Formatting values into strings goes in simple cases by straight string concatenation like in $i.... for stronger control, format is comparable to sprintf
  • puts, unlike printf(), emits a newline by default.

AM The above proc could look like this in Fortran (90):

  subroutine countdown( n ) 
     integer :: n
     integer :: i
     do i = n,1,-1
        write(*,*) i, '...'
     enddo
  endsubroutine 

The main difference with either C or Tcl is that in Fortran the do-loop is very different kind of control construct: it is really an iteration over a predefined set of values, whereas in C and Tcl the three parts gouverning the iteration can be almost anything. (The Fortran control variable can be an integer only).

Scheme

 (define foo 42)                 | set foo 42
 (define (square x) (* x x))     | proc square x {expr $x * $x}
 (define bar (square foo))       | set bar [square $foo]
 (define grill '(square foo))    | set grill {square $foo}
  • Functions are also defined with the proc command. Their result is the last executed command in the body
  • Arithmetics is not done with prefix functions, but Infix-style like in C, in the argument(s) to the expr command
  • set is used for variables, proc for functions - no unified define in Tcl (except if you write one - see the Scheme page ;-)
  • Tcl commands on toplevel are not enclosed in parens. Embedded commands like the first call to square go into brackets for eager evaluation; the equivalent to quoting is curly braces around a string
 (define (abs x)                 | proc abs x {
   (cond ((> x 0) x)             |    expr { $x > 0?  $x :
         ((= x 0) 0)             |           $x == 0? 0 :
         ((< x 0) (- x))))       |           $x < 0?  -$x}
                                 | }
                                 | or: proc abs x {expr abs($x)}
                                 | or: proc abs x {expr {$x<0? -$x: $x}}
  • expr can, with the ?: operator, operate like cond
  • It also has built-in math functions that can be exported in a one-liner as shown (Importing expr functions)
  • Tcl needs less parens (which often amount to braces or brackets)
 (define (abs x)                 | proc abs x {
  (if (< x 0)                    |    if {$x < 0} {
      (- x)                      |        expr -$x
      x))                        |    } else {return $x}
  • If,for,while take a test expression in infix notation, as used for expr
  • The branches of an if must be commands - in place of the return x one might write set x

LaTeX

  \IfFileExists{foobar}{             |  if {[file exists foobar]} {
     \saved@cnt=\cnt                 |     set saved@cnt $cnt
     \input foobar                   |     source foobar
     \cnt=\numexpr\saved@cnt+1\relax |     set cnt [expr {${saved@cnt} + 1}]
  }{\errmessage{No file foobar}}     |  } else {error {No file foobar}}}
  • Tcl and (La)TeX both have braces as the chief delimiter, and may use them around data just as well as around blocks of code, but in Tcl you must leave whitespace between a closing "}" and a following "{", whereas in (La)TeX people normally don't, although you may leave whitespace there.

aa This is misleading enough that I'm going to call it wrong. Tcl's "chief delimiter" is simply whitespace. Braces (and quotes) are used to override that, turning strings that include whitespace into single words. Lars H: The majority of all Tcl code appears as the bodies of procedures (indeed as a brace delimited word), does it not? (Well, if it didn't then Why can I not place unmatched braces in Tcl comments wouldn't have been much of an issue.) For all this material, the primary rule is that (non-blackslashed) braces must balance! This is how braces are the chief delimiters -- perhaps not in the rules of the endekalogue, but in practical code, and more inportantly: in the mind of the programmer.

I think the very fact that, in your words, "you must leave whitespace" between curly braces, curly braces can't possibly be the chief delimiter. The space (or whitespace in general) is the chief delimiter. Curly braces are an optional quoting method. It is possible to write an entire Tcl program without curly braces but I'm not sure it's possible to write one without whitespace.


See also BOOK Programming Language Examples Alike Cookbook, http://www.merd.net/pixel/language-study/scripting-language/ and CL's ill-maintained personal notes on language comparison [L1 ].


Tcl and other languages