In the Mindshifting May introductory video [link] Erik’s Tcl notes were:
Introduction
Originally developed by John Ousterhout whilst working at the University of California, Berkeley. Developed in the late '80s as an extension language for Electronic(s) design automation (EDA) applications (software tools for designing electronic systems such as integrated circuits and printed circuit boards) which were his professional focus.
Originally, it was envisioned that the Tcl code would be used as “glue”, and that all important functionality would be coded in C. But the Tcl language has evolved to be fully-featured in its own right.
Tcl, pronounced “tickle” is short for Tool Command Language
It was designed with the goal of being very simple but powerful.
General purpose, can be used for scripts, embedded, used for building websites or GUIs (via the Tk framework)
Multi-paradigm: object-oriented, imperative and functional styles are supported
Dynamic language
Open-source
Used in CISCO router GUIs, various manufacturing systems, NASA has used it on many occasions, Pixar, Boeing, Intel, NBC, and many more. Tk, the windowing toolkit, has been adopted by other “scripting” languages like perl/python/ruby. Expect, a tool to automate interactive CLI applications
Why it’s great
Very little syntax, just 12 rules and it fits on a piece of paper. Semantics are also relatively straightforward. Makes programs easy to read and learn
Simple concurrency via coroutines, which allows asynchronous code to be written like synchronous code
Built-in event loop for network programming and asynchronous file I/O
Mature, but still evolving
Standout features
Straightforward type system: everything is a string. “Everything is a string” was how Tcl used to be implemented. Now, under the hood, there is a robust type system, where the Tcl entity (be it a string, float, list, dictionary) has a type-specific representation as well as a string representation. This greatly improves the performance of Tcl code, as it no longer needs to convert back-and-forth from strings.
“Everything runs as commands”. There are no builtin commands. Tcl ships with a “standard library” of commands, including if and while, etc. It’s very simple tadd new control flow commands: for example an until loop. It’s also easy to override Tcl command.
Due to being compact, simple semantics and being implemented as a C-library, easy to embed
I don’t particularly consider Tcl as “mindshifting”. The syntax feels somewhere in between shell and Lisp. It’s a largely imperative language with procedures (i.e. functions). The data structures are pretty familiar: lists (arrays) and dictionaries (maps)
“Everything is a string” means that quoting is important. Like shell programming with double quotes and single quotes, Tcl has interpolating and non-interpolating quotes:
double quotes allow variable substitutions (and other form of substitution)
set name Fred
set greeting "Hello $name"
puts $greeting
# => Hello Fred
Note that Fred does not need to be quoted: the set command takes one or two arguments, the second argument is just interpreted as the value.
curly braces are the non-interpolating quotes. No substitutions are performed
set greeting {Hello $name}
puts $greeting
# => Hello $name
The proc command takes 3 arguments: the proc name, the argument list, and the body.
proc greet {name} {
return "Hello $name"
}
greet Fred
# => Hello Fred
When you see braces used to enclose the arg list and the body, this is not special syntax: it is merely quoting the arguments to prevent variables from being substituted too soon.
sh does not honour the comment’s line continuation and executes the exec line. But Tcl sees the first 3 lines as plain comments and starts evaluating the Tcl code
Karl Lehenbauer, former CTO of FlightAware, was a creator of TclX, a library of useful extensions. Many of the features have been incorprorated into the Tcl core. FlightAware offered substantial bounties for improvements to Tcl.
Tcl is losing out to Lua in this regard, I believe. The Tcl core is getting larger, so it’s not as small as it once was. And Lua’s syntax is a little more mainstream.
I’d add my 5 cents into the what makes TCL different:
substitutions aren’t just “in arguments”, it’s everywhere:
set command set
$command command proc
$command test {} { puts "test" }
test
will print “test”
Previously we used subst command to unroll lists into literal lists of arguments; since 8.5 there’s a language construct {*}:
set something {a b c}
my_proc $something ;# will call my_proc with a single agrument which is a list `{a b c}`
my_proc {*}$something ;# will call my_proc with three arguments, `a`, `b` and `c`
Also it was funny to see how dict command was implemented in pure TCL to retrofit into older versions. I used that in my code that was running in Cisco routers (which included TCL 8.3 with no dict).