Re: Why you should not use Tcl

Wayne Throop (
27 Sep 1994 18:28:08 GMT

:: Tcl has procedures with lexically scoped variables.

: From: "Daniel C. Wang" <>
: Tcl is not lexically scoped in any meaning of the phrase, it like
: elisp is dynamicly scoped. Hence hacks like upvar, uplevel, and the
: need to have a "global" deceleration.

This turns out not to be the case. Consider the elisp:

(defun a () (setq x 1) (print x) (b) (print x))
(defun b () (setq x 2))

compared to the analogous tcl:

proc a {} {set x 1; puts $x; b; puts $x}
proc b {} {set x 2}

The (a) in elisp prints 1 and 2. The a in tcl prints 1 and 1. In the
default case, b is prevented from trashing a's state, while (b) is not
prevented from trashing (a)'s state.

In this simple (and I argue, "meaning"ful) way, tcl has lexical scoping
of variables. In fact, it is exactly this restriction of variables to
have the scope of the enclosing proc body that makes it necessary to
have upvar, uplevel, and global. And it is exactly this feature that
makes tcl variables a bit harder to shoot yourself in the foot with
in large scripts. Not impossible. Just a bit harder.

In "dynamically scoped" notations, you have flow-control-nesting
let bindings (or perl's "local", or whatnot). And if you leave them out,
you start clobbering nonlocal state. In "lexically scoped"
notations, you have no need of them (they are implicit with the swap
in lexical scope), but you may need explicit scope manipulations in
order to be able to, eg, write control flow operations in the language.
And if you leave them out, you can't access nonlocal state.

Hence my original mention of this feature (under the name "lexical
scope" in responding to the notion that tcl has no designed-in
provisions to make large scripts more tractable.

: If Tcl were indeed lexically scoped, and included a real lambda
: abstraction, it would be almost trival to build up a object system
: without having to extend the lanuage with an extension like [incr tcl].

This seems to conflate the notions of lexical scope and lexical closure,
which are actually distinct. In CLTL, lexical scope is defined in terms
of references to names being *dis* allowed outside a textwise-contained
region. It doesn't logically imply that reference can bemade
*everywhere* *within* the textwise region (even inside enclosed proc,
for a tcl example).

Further, [incr tcl] isn't actually an extension of the basic language
(IMHO), any more than "printf" is an "extension" of the basic C
language. That's one of the nice things about tcl's "lazy" attitude
towards the interpretation of text. The commands give the semantics
to the notation, instead of the parser doing so. Though many may
disagree, I think that this is very very often a Good Thing.

Wayne Throop