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!
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 } }
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).
(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}
(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}}
(define (abs x) | proc abs x { (if (< x 0) | if {$x < 0} { (- x) | expr -$x x)) | } else {return $x}
\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 | (La)TeX |
---|---|
Tcl has explicit separators: newlines or semicolons between commands, whitespace between words, etc. Only some forms of variable and backslash substitution exhibit greedy parsing. | Parser is greedy and considers a syntactic entity to consist of everything up to the first token that cannot be part of it (this is a common source of strange errors and also the reason for most uses of \relax). LaTeX often replaces greedy TeX constructions by self-delimited constructions (e.g. \frac instead of \over), but sometimes the underlying greediness shines through. |
Commands and variables are different things. | Variables are mostly a kind of command: macros defined to expand to the values they store. There are some families of registers which are purely variables, but even these are typically accessed via (and often informally identified with) particular commands. |
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 ].