Tcl Me Pink
By templedf on Aug 11, 2005
The Grid Engine test suite is written in Tcl. Tcl is in odd language. When I first started working with our test suite, Tcl made no sense to me. After I had worked with the test suite a bit and written a few tests, though, Tcl still made no sense to me. I got by by copying already existing tests and making changes. Only now, after writing a relatively complex test from scratch do I feel like I actually understand Tcl.
The real breakthrough for me came when I realized how similar Tcl is to LISP. OK. Perhaps similar is somewhat of an overstatement, but the strange way in which you have to contort your mind to write code in both languages is similar. In my opinion Tcl is to LISP as Perl is to Borne shell, i.e. more complex and more powerful.
Everything in Tcl is a string. Every string can be treated as a whitespace-separated list. There are lots of routines for doing interesting things with strings and lists. Tcl is also a functional language, hence the mind bending required to develop in it. For example, if I wanted to take the string "This-This-has-dashes-in-it", remove the dashes and the extra "This", a very Tcl way to do it would be:
set newString [lrange [join [split "This-This-has-dashes-in-it" "-"]] 1 end] # newString is set to "This has dashes in it"
The first thing that should jump out at you is the functional programming style. The brackets indicate that the bracketed expression should be executed and replaced by the results from the execution. The next obvious thing is that most of the normal trappings of a programming language are missing. There's no parentheses (Big difference from LISP!), no semi-colon, no equals sign. I suspect the plan was to have a language that looked as natural as possible. The result, though, is something that causes the average developer to stare blankly for a few seconds while recovering from code shock. (It's like culture shock, but for developers. It also occurs when a JavaTM language developer looks at pointer arithmetic.)
Tcl also has the odd habit of treating every code block as a separate program. Tcl programs are executed from the inside out. The inner-most code block in a statement is executed first, and its results are used in executing the block that contains it. That sounds half-way reasonable until you notice that everything in Tcl is a code block. The conditionals on if statements and while loops are code blocks. Every segment of a for loop's conditional is a code block. The pervasiveness of code blocks becomes a problem when trying to debug a Tcl script. Instead of giving reasonable information about where an error occured, you get an unwinding of the code block stack that led up to the error. It's a lot like a Java platform stack trace without the line numbers.
Tcl is not all bad, though. It does have its uses. There's a reason why we use it for our test suite. I don't actually know what that reason is, but I'm sure it's a good one. Why else would we subject our developers to writing tests in Tcl?