Re: Why you should not use Tcl

Wayne Throop (
3 Oct 1994 21:19:46 GMT

[ Note: I've truncated the newsgroups line, largely because of
requests from readers of comp.lang.scheme ]

: From: (Niels P. Mayer)
: Why not start with a language that was
: designed to be semantically and syntactically elegant right from the start?

Because it wasn't designed to be lexically *minimal*, which is important
in an embedded language, but was not so important in the design of lisp
and variants. I am not fully satisfied with tcl in this regard either,
but I think a reasonable case can be made that tcl has attractive
features in this regard that ought not be discarded lightly.

: For one, "scripting" languages don't handle the data abstraction, and
: manipulation required by most non-trivial applications, and you really
: shouldn't need to drop down to the C level to implement such
: capabilities.

But this is a philosophical position, not a technical fact-of-the-matter.
Not that I strongly disagree, but part of the philosophy of tcl is
that an *embedded* scripting languge *shouldn't* handle data abstraction
directly, and that the application in which tcl is embedded should
decide what abstractions are appropriate, and what notations and
implementation strategies are good ones.

: Also, anybody that knows anything at all about languages knows that it
: takes very few language capabilities in order to perform arbitrary
: computation. So claims that TCL is a good language because many
: people are writing apps in TCL does not mean that the language is good.

I certainly wouldn't base a claim that tcl is a good scripting language in
the fact that people actually write scripts in it. Foo, when forced to
do so, I've written significant scripts in nothing more than hordes
of "regsub"-like text replacements.

But out of the programming constructs I use, tcl isn't missing many.
Yes, it is missing some of the favorites of the lisp community, such as
anonymous functions and lexical closures. But it unifies the concepts
of functions, macros, and special forms into a single construct,
provides lexically local namespaces by default, non-local
goto/error-recovery structures, and with [incr tcl], provides
class/method object semantics.

Therefore I think it is by no means fair to say that tcl's programming
constructs are significantly impoverished.

This is not to be confused with the question of whether tcl's
available primitive capabilities are impoverished relative to lisp.
Yes, lisp has bignums, ratios, vector arrays, symbols and lists,
structures, and so on and on. But many, even *most* of these cases
where lisp exceeds tcl is not in a particular abstract area, but in
how many optimized implementations of an abstract facility are
available. The example of arithmetic is illustrative: in Tcl, there
are only integer and floating-point semantics, and even then, the
interaction of these with variables is via text substitution. In lisp,
there are fixnums, bignums, floats, ratios, and complex numbers.
Or take modularity. Tcl "has" [incr tcl], while lisp has packages,
closures, and CLOS.

So, yes, lisp and scheme have more programming constructs and more
primitive data types to call upon. Many times more. But because of
overlap among lisp features, when considered as a user-visible scripting
language, tcl consistently kills 80% of the birds with 20% of the stones,
and thus arguably has a significantly more manageable learning curve.

I realize the "tcl has a learning curve advantage" is itself not
without controversy. After all, scheme in particular is pretty spare
and clean, and one can be up and writing significant programs quite
quickly. A lot of the complexity of lisp and scheme compared to tcl
is effectively managed by the dynamic typing of the language, so that
it DWIMs nicely. Nevertheless, tcl is at the very least at no disadvantage
in terms of "quickly being able to write significant programs", IMHO.

: Since nobody seems to be making any specific points about what is
: wrong with TCL, I thought I'd repost two articles I've posted in the
: past, during a previous "language war". [...]

: It looks like a number of your users are also having trouble
: understanding Tcl. In my opinion, this is because the quoting and
: parenthisation rules are neither straighforward, simple, nor
: consistent. About once every week or two, I see questions come up on
: comp.lang.tcl dealing with one or more of the issues raised above.
: Examples of these problems have been appended to the end of this
: article...
: [.. 1) used {catch [foo]} instead of {catch {foo}}
: 2) used {foo $bar} instead of [list foo $bar]
: 3) lack of general evaluation in default argument values
: 4) expr lexical rules ..]

I definitely appreciate having specific points called out.

Of course, the question the tcl advocate must answer is *why* do people
make mistakes such as those above in tcl, if the rules are so easy?
After all, people don't often write (foo 'bar) when they mean (foo "bar")
in lisp, so why do they write {foo [bar]} when they mean
{foo {bar}} in tcl?

My conclusion is, they simply didn't learn the rules. By which I don't
mean that they tried and failed to learn the rules, but that they didn't
spend time learning the rules in the first place. That is, tcl errors
are made by a self-selected group of people... a group of people using
tcl because of it's shallow learning curve. A group of people who,
I contend, would be *even* *more* confused by lisp (or C or many things).

Granted, I don't have statistics and controled studies to back up this
contention. But again: the {catch {foo}} vs {catch [foo]} error is an
error akin to writing (foo 'bar) or (foo |bar|) when (foo "bar") is
meant. Similar things are true of the other cases above. Whatever the
actual cause of this confusion, I cannot see how it can plausibly be
because tcl's rule of "[] always evaluates and {} always quotes" is
"too complicated". Let's be serious folks, whether a Good Thing or not,
this rule is *not* complicated.

To conclude, I agree fully that lisp is a "real programming language",
something that tcl probably can never be. But it isn't at all clear
that RMSs contention that a scripting language "should be" a "real
programming language" in this sense is correct. It isn't at all clear
to me that a single language can scale all the way from the needs of a
general scripting/command/extension language though the needs of the
most demanding of algorithms and data structures.

I submit to you that tcl (or some close relative) can just as easily act
as a "glue" language for an application largely written in lisp as it
can in other languages. In fact, I've seen things done in exactly that
way, for very deep customizability: application libraries written in
lisp, with a tcl-like command language, and with a well-defined mapping
from the one to the other.

RMS proposes to have two languages, both of which scale all the way from
simple users to the most complicated cases. Tcl advocates propose to
have two languages, one of which concentrates on power and
functionality, the other on being lexically inconspicuous glue with a
shallow learning curve. I submit to you that RMS's pair of languages
decompose the domain in the "wrong direction", both being vertical
monoliths instead of being horizontal layers with modest goals.

Wayne Throop