Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Heart️ for Tcl.

Tcl wasn't my first language, but it's near and dear to my heart. It's a little oddball for sure.

I can't decide whether it's Python trying to be Bash, or Bash trying to be Python. But it's surprisingly expressive.

Everything is strange about the syntax - from "everything is a string" to "expr" to the weird variable-assignment syntax.

It's also really tiny, and has a great async event-loop framework. It has built-in support for sockets and non-blocking I/O. It has a GUI toolkit that's pretty useful for making quick-and-dirty tools. It's incredibly easy to use interactively with a REPL. And it's still the scripting language of choice for the FPGA industry, which is where I got my start as a software engineer.

The Tcl community is small and stable. And the language just keeps soldiering onwards, in a gradual way. It feels like it's been stable and fully-realized for the last 20 years. No breaking API changes, no syntax changes. It just keeps on keeping on, providing automation to tools that need it. Tcl has outlived a bunch of newer languages, and I hope it sticks around for another 20 years.



Tcl is a Lisp with bash-like syntax and features.

I have a strange test for languages - I tried some of them being drunk (a litre of some nice tripel). This test tests how effective can you be with diminished higher-order thinking, or, in other words, how much of your mental ability each tested language takes from you.

Tcl has immutable proc arguments - if you pass somewhere a value you can be sure the value at caller's site stays the same. It happened that this means a lot and one can (semi)successfully program in Tcl while being drunk.

Every language where arguments' values modification is visible to the caller is much worse in that regard, these are C, C++, C#, Java, Python and Perl (and many more). Aother bad feature is a null pointer - Per is better here.

Tcl does not have modifiable argument values except you are really want them (upvar and uplevel). It also has multivalue assignment in the form of "foreach {resultpart1 resultpart2} [procedure arg1 arg2] break" (or you can invent your own mutivalue assignment procedure). This makes building composable libraries quite easy.


The immutability and the lack of null are a big part of why Tcl is my favorite scripting language. I learned other languages at a similar level of abstraction before Tcl, but now when I program in Python or JavaScript their mutable collections feel like an obviously wrong default.

[upvar 1] and [uplevel 1], which, respectively, link a variable in your caller's stack frame to one in yours and run a command in the caller's stack frame, usually compose nicely. They are Tcl's replacement for macros and the lack of a compile time/run time distinction makes them, in a way, easier to reason about. However, [upvar N] and [uplevel N] aren't limited to N = 1, your immediate caller's stack frame. You can reach up an arbitrary number of stack frames. It allows you to design really complicated control structures. [upvar] links also nest. You can fall into a pattern of carrying around some sort of a context or configuration data with nested [upvar]s like a poor man's Reader monad. Both are difficult to debug when they go wrong and should be implemented with care and only when necessary.

Since version 8.5 Tcl has a built-in command for assigning list elements to variables:

  lassign [procedure arg1 arg2] resultpart1 resultpart2
Conveniently, it also returns the remainder of the list if there were more list elements than variables. It leads to the idiom

  set list [lassign $list foo bar baz]


Tcl is _famous_ for allowing to program in it while drunk (and get some good results). This is why it is somewhat popular in the academia / scientific engineering circles. :)


Saved me while in academia many times.


> Python trying to be Bash, or Bash trying to be Python

The fact that "everything is a string" is cute and odd but the end result is really closer to shell scripting than a real object-oriented language like Python. You routinely have to deal with string/list quoting and constructing complex data structures is tricky if they have to be represented with just strings and hashes.

Sure: it's flexible and you can reimplement all the features of a high-level language but I'd rather use a language which has all the features already.


Tcl has native support for lists and dicts, and provides full-featured functions for working with both. You're absolutely right that the feel is "more than Bash, less than Python." But it's not accurate to say that you need to do a bunch of weird string parsing in order to implement a high-level datatype.

And yes - the list quoting rules are weird! No doubt about that.


I tend to call it "bash bitten by a radioactive lisp"


I have an old engineering program that uses tcl as its scripting language... stuck on a version that predates dictionaries.

Without dictionaries complex data structures are quite difficult, and people will abuse the heck out of the language to create them. I was just looking at an example where some poor engineer was inventing a "data structure" by using string manipulation to create & modify variable names. Some of the variable names he derived were also defined as globals, so there was that too.

Prior to dictionaries, tcl only had arrays, which are the least string-like things in the language.


> And yes - the list quoting rules are weird! No doubt about that.

Lists might be "native" in the sense that the interpreter knows how to deal with them but in the data model there is no distinction between a "string" and a "list of strings". A list is just a space-separate string with quoting rules and the difference is entirely in manipulation.

It's easy to make quoting mistakes so a program might start breaking when arguments contains spaces: this almost never happens in languages other than shell.


> A list is just a space-separate string with quoting rules and the difference is entirely in manipulation.

This has not been true since the release of Tcl 8.0 that added the Tcl_Obj subsystem.

Lists in modern Tcl (8.0+, with 8.0 released in 1997) are proper O(1) indexed arrays. Yes, you can still request from Tcl the 'string' representation of the O(1) indexed array, and the result you get is the old (pre 8.0) "space-separate [sic] string with quoting rules" variant that will parse back into the O(1) indexed array later if you want.

But Tcl lists have not been /only/ those strings for a very long time.


Dicts are implemented using hash tables and thus slow on pass to procedure that modify them. I had to switch to Python and then C when I encountered quadratic runtime using dicts.

I hope they will use something like hash-array-mapped trees someday. It will make things much faster.


Thats not quite true since the early 2000s, when dictionary structures came around. Tcl also has strong built in object oriented support since 8.6 (2012) so if you like that sort of thing its there.

If you are dealing with quoting issues that's probably due to you using an older version like 8.3 or 8.4. Give a newer version a shot!


Tcl/Tk was a tremendous rapid GUI prototyping tool. I remember cobbling together a Verilog schematic viewer in a couple of weeks using that combination, for the Series A funding round of the startup I was working at in the early 2000s.


This was my reason for foraying into Tcl too. Till then I had used Java's AWT and Swing; but prototyping with Tcl/Tk was way faster and intuitive. Mid-2000s. I ended up liking the language - idiosyncratic as it was. Partly the reason I am curious about and planning to read Ousterhout's (creator of Tcl) book "A Philosophy of software Design" soon.


It’s a great book (only one reference to Tcl that I recall though). Also Perl/Tk was the first GUI toolkit I used (followed by Glade).


The event handler based vector graphics in Tk were unmatched until HTML 5 and the canvas. And then there was the easy and fantastically well documented C extensibility...


Tagging system of Tk's canvas is unmatched in HTML. Pity they (HTML designers) never learn.

Basically, in Tk, you can add a tag to an element of your drawing in canvas and assign mouse (or keyboard) event handlers to change colors or other attributes on entry and exit of mouse cursor.

I made a OO/relational database schema visualization in Tk, it was breese to navigate - once you hover over a relation, you can see classes highlighted; follow highlighted relation to get to them. And once you highlight class of objects you can see to which relations it belongs.

It tooks two foreach loops to get that behavior. As far as I know, HTML5 canvas does not support that out of the box.


HTML canvas indeed doesn’t support hit detection – although SVG does, and you can embed SVG in HTML.


I think it still is. A very easy to use, quite well working cross-platform solution. Since 8.6, the UI has picked up a much more nativel look and feel.


You have no idea how much I wish i could interact with a simulator using something other than tcl, preferably python.

I don't have anything against tcl per se, but I can't think nearly effectively about anything because tcl doesn't really live anywhere else that I work. I can appreciate that it has the audacity to thrive in the tools I have to use, but I always sort of pine for what could be.


Tcl is good for interacting with a simulator (and other tools) for the same reasons Bash is good for interactive shells, and I think Tcl is the best tool for those jobs.

What is the "could be" that you pine for?


so like one instance I had is making a big input vector for running my testbench against. JSON, CSV, work with it in a dict or list, anything that I sort of already knew in python was better than what I cobbled together.

It's nothing against TCL, and it no doubt has the power to do it, it's just up I do FPGA stuff, python is my swiss army bludgeoning device. It's just like EDA tooling is like, the #1 place where I wish python lived, but it's TCL's stronghold.


And yet I still can't get my head around upvars.

I really like TCL, I've been using it in conjunction with NaviServer known as AOLServer back in the day (which mind you has some interesting history).

TCL is a fun little language and combined with Navi -- you can really create some crafy webapps.


> And yet I still can't get my head around upvars.

I haven't used Tcl for maybe 15 years, but if I recall correctly upvar was basically an alternative to lack of pointers.

What it was doing was giving you access to a variable from specific stack frame.

You could say I want to access variable from the function that called me.

upvar and it's interesting syntax allowed to create new "statements" for example in earlier versions of tcl (because looks like it was added later) you could implement try-catch "statement" and it would behave as if it was part of the language.


> upvar and it's interesting syntax allowed to create new "statements" for example in earlier versions of tcl (because looks like it was added later) you could implement try-catch "statement" and it would behave as if it was part of the language.

This is one of the things I miss most when using other languages. Outside of actual lisps (of which I consider Tcl to be one), there's very few languages that allow you to build your own control structures. Ruby comes close, but doesn't really have the same flexibility.



Did you come into aolserver via Philip greenspun and arsdigita like so many folks?


Not really, I've come from perl. My half built web project is still sitting stable as ever since not touching it in many months, looking at it; it's like entering a overgrown temple. Knowing if you make an alteration the whole temple can collapse.

TCL just seemed to fit and discovering naviserver could do "register domain/home execute procedure return html" without having to create a mess of routes, models and all the rest just kind of made me happy.


I always views TCL as closer to Lisp and Forth - almost no syntax, the tools to build new control structures, a simple underlying data model.


> It's also really tiny, and has a great async event-loop framework. It has built-in support for sockets and non-blocking I/O. It has a GUI toolkit that's pretty useful for making quick-and-dirty tools.

There are implicit "OR" statements between those sentences.

Example: suppose a newbie wants to use tk do make a quick-and-dirty GUI and leverage tcl's async event loop to make it responsive while processing a bunch of files. It's my experience that while this can be done it is less than easy.


This can be tricky, because programming based on events tends to push you into writing everything as event-handlers, but they get awkward for long-running stateful computations. However Tcl has had coroutines for about 10 years now, and those allow you to bypass this problem completely.

I gave short presentation about applying this approach to scripts combining a responsive GUI with managing multiple parallel Expect sessions at www.eurotcl.eu/program.html#Macleod .


I don't recall that being the case. Has something changed in the past years that prevents you from using the same event loop for both gui and async behavior?


Well upvar makes porting harder.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: