Re: Why you should not use Tcl

Wayne Throop (
29 Sep 1994 17:12:15 GMT

: From: (Darin Johnson)
: And this got me to thinking that perhaps there are a lot of Tcl users
: claiming that it's simpler to use than Lisp for the same sorts of
: reasons. They've heard that Lisp is hard, and they figured out Tcl,
: so Tcl must be simpler and more elegant.

An interesting perspective, but I think there are legitimate reasons
for a claim that tcl is simpler than lisp, and more approachable as
a scripting language.

In approaching each language for the first time, just consider
explaining how the basic forms of the language are interpreted. In
lisp, you tend to have a discussion about functions, macros, and special
forms, and why it is that you sometimes need to quote things, and
sometimes you don't because the context does it for you, and why some
things are funcallable and others aren't. And to write macros of any
complexity, you need quote and backquote and on and on and on.

In tcl, the evaluation rules are a tad simpler and more lexically
explicit, and while there's still the need to explain things like the
fact that conditional expressions and codebodies get rescanned while
most commands don't rescan their arguments, this is a property that is
regular and applies to all invocations, rather than a distinction of a
*kind* of invocability.

This same contrast applies to lots of other topics, like variable
namespaces, symbol namespaces, data types, and many more. Try
explaining EQ/EQL/EQUAL, and why fixnums and bignums behave as they do,
as compared to a similar explanation for tcl. And that's before we even
get into historical bizarities like why both CAR/CDR and FIRST/REST. In
each case, tcl kills 80% of the birds with 20% of the stones. This
makes the learning curve for tcl noticeably less steep than that for lisp.

Note I am not saying in any way shape or form that tcl is "better" than
lisp, or that lisp is *fundamentally* a hard language to learn. I'm
saying that there are legitimate reasons for categorizing tcl as
"simpler" than lisp, and legitimate reasons for supposing that the kind
of simplicity tcl displays is useful in many scripting language domains.

Taking off on a tangent related to a specific case of "simplicity", I'll
even take the bizarre stance of criticizing both tcl and lisp for being
too lexically complicated to make a good scripting language (!!?).  

Yes, you heard. "Lexically too complicated".

lisp: ; " ' | () # ` , \s [0-9/+\-] [a-zA-Z] : tcl: # " {} [] $() \s \ \n ;

In a scripting language, I prefer something at least a little more spartan. The reason is, the application into which the scripting language will be embedded will doubtless have its own notational conventions. To have "all the good characters already taken" by the scripting language means that lots of quoting needs to go on. Some relevant tricky tradeoffs are,

- should variables and procedures overload a convention, so that [] and $ can be unified or partly unified - should you stick to \n and \, or go with explicit ; (or ()) for line-spanning statements (and note that whether there is a read-eval-print loop being typed at can affect this tradeoff) - should commands each be able to specify inter-argument separators and quoting/bracketing conventions, or should they be lexically static

Despite other shortcomings, I particularly like DG's mxdb debugger's command language's choice of lexical tradeoffs. But then I'm prejudiced, since in a former life, I participated (as a junior hanger on) in the design of that command language. Suffice to say, (at least in the language's purest form... some "corruption" occured later) the only characters at top level that are *interpreted* by the lexer are whitespace, backtick, and comma (though some others have some minor lexical significance).

Another language with somewhat extreme minimalism (at least insofar as I understand it... I admire it more from a distance than DG's cp), is SMDS's lakota.

Now why is such ... "extreme" (to say the least) lexical minimalism valuable? Again, in a *scripting* language, specifically an *embedded* scripting language, it is valuable because the application being scripted is then free to introduce notational conventions of its own, without tripping over an "outer" or "encapsulating" set of lexical/notational conventions. This is important for DG's mxdb, because that command language needs to be able to manipulate expressions in multiple programming langauges. This is important for lakota, because (I think) it is a command shell that needs to run in multiple environments, and hence needs to adapt itself to to multiple "shell" syntax conventions.

I feel that this "lexical minimalism" is a much-overlooked and seldom-provided feature of a good general-purpose scripting language, and tcl (while IMHO slightly deficient) comes closer than many another to having it. Consider, for example STk and tkperl, as compared to tcl notations for the same thing.


(define f (make <Frame>)) (define l (make <Label> :parent f :text "A simple demo written in STklos"))


$f = Frame::new($path); $l = Label::new($f, "-text" => "A simple demo written in tkperl");


frame .f label .f.l -text "A simple demo written in tcl/tk"

Now, the point is, there are startlingly fewer "noise" characters in the tcl/tk example. And the reason is, in scheme and perl, there are already notational conventions in the language for how objects are supposed to be refered to, how objects get parents, how keyword arguments are denoted, how constructors ought to be specified, and so on and on. In tcl, on the other hand, the *application* was free to design most of the notation, and thus could streamline it to the specific case, while the tcl language itself stomped only on the outermost global namespace to keep multiple applications out of each other's hair.

Granted, *some* of the "noise" characters come from an incomplete conversion of the tk toolkit, but on the whole, the tcl/tk example profits by making the parent/child relationship an abbreviated notational convention, and the lack of variable, namespace, and quoting markers.

Just as a lark, btw, here's how a hypothetical cp/tk example would look (the DG mxdb command processor I refered to above)

frame .f label .f.l, text A simple demo written in (hypothetical) cp/tk

Wayne Throop