the Zen of Tcl

A string isn't anything - It just Is

Richard Suchenwirth 2004-02-19: I created this page by accident - I thought it existed... Now it exists. First lesson in the Zen of Tcl: wishful thinking helps to make things come true.

  • The Tao of Tcl
  • Everything is a string
  • It's simpler than you expected
  • But then again: everything is a command. (This unifies declarations, subroutines, functions, but conflicts with #1. Well, Tcl has never claimed to supply the Grand Unified Theory, and yet, in some ways it does.)
  • The solution you can implement is not the true solution
  • Errors are friends, they help you get better
  • Errors show up mostly at runtime - so, run (test) your code as early as possible

FW: In an effort to start this line of thought off resembling the page title (unlike the Tao of Tcl, which really doesn't have anything to do with Tao), I'll start off with the big principle:

  • Desire breeds suffering.

A Zen program is a solution. It doesn't, as much as possible, solve a problem - it just is. This is hard to describe. Tcl as it is is already a fairly Zen language. In a Zen state of mind subject, object and action become too correlated to distinguish - this parallels Tcl's observation that "all is a string," where action and actor - data and code - aren't restricted from integration. A very Zen solution is the classic:

set r [expr [join {4 5 6} +]]

. Within that expression is data as text, as a list, as integers, and as part of a code body. It's not practical, but it's a compact example. Data and code flit around effortlessly, never clashing, in harmony. There is no step by step in that solution like there is with this version:

set r 0
foreach i {4 5 6} {
    incr r $i

. That solution tears the problem apart into pieces and does them step by step, kind of enforces a structure on the issue. The programmer's "ego" - his personal technique of interpreting how the problem is broken apart - is more involved. But the earlier solution has a kind of, well, Zen to it. This shares some ideas with functional programming - the idea that a program is a set of interrelated values which just cascade down into a solution naturally, without a strict order. But while functional programming encourages this type of style, it largely just forces it - an imperative language as flexible as Tcl can do things in that way, if without the same abbreviating idioms, plus is afforded the whole richness of the imperative world when it's needed.

(Note that in the example I gave the second, "worse" code is actually the more efficient, correct way to do it - it's just a very compact, well-known example.)

RS: The above example boils down into the function

proc sum list {expr [join $list +]}

but the inefficiency is demonstrated in elegance vs. performance. And still I love elegant code...

AMG: This can now be written very efficiently:

interp alias {} sum {} ::tcl::mathop::+

RS It doesn't have the same API, though:

% interp alias {} sum {} ::tcl::mathop::+
% sum {2 3 4}
can't use non-numeric string as operand of "+"
% sum 2 3 4

With an eval added, it accepts arguments both as separate words or as a list:

% interp alias {} sum {} eval ::tcl::mathop::+
% sum 2 3 4
% sum {2 3 4}

RS had another Zen moment when coding (see Functional programming for details)

interp alias {} ! {} o product iota1