Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why I'm Tcl-Ish (colin-macleod.blogspot.com)
167 points by blacksqr on Oct 26, 2020 | hide | past | favorite | 122 comments


I love TCL. The author points out my favorite aspect: "it has a radical minimalism". I use it for hobby projects because I work in Python all day professionally and like to mix it up a little in my free time. It feels very different but inhabits the same use case space.

That being said, here are some interesting things that tripped me up:

- using expr for arithmetic. The author mentions it, and it is cumbersome, but it also exemplifies what makes TCL special

- upvar for pass by reference. TCL does pass by reference by the command upvar, which says "take the variable named x in the scope above and assign it to the variable y in this scope". Confusing at first but a nice way to have pass by reference in a dynamic language

- docs are hard to read sometimes. The manual and tutorial for TCL are fantastic; the wiki is a little hard to read sometimes. The pages kinda seem like conversations, with authors weighing in on an article and tagging their names to their comments.

- lack of structured data. Saw another commenter posted this, and its something I wish TCL had better out of the box support for. The addition if dict was huge. The good news though: it's extremely easy to build a new command set to build a data structure out of dicts.

Despite all of this I'm a big fan of TCL. I try to tell as many people I can about it, because it really feels like a breath of fresh air compared to my day job Python. It allows you to be creative (and reckless!) with its power.

Edit: going to post the tutorial because it's so essential to getting started: https://tcl.tk/man/tcl8.5/tutorial/Tcl0.html


It's easy to alias expr to =, which enhances readability :

  % interp alias {} = {} expr
  =
  % set x [= 2 + 3]
  5
Also aliasing lindex to @ is nice

  % interp alias {} @ {} lindex
  % set a {1 2 3}
  1 2 3
  % @ $a 1
  2


Python includes a Tcl, you should be able to use Tcl inside your Python projects just fine technically. Socially, might not work out.


In newer TCL (8.5+) you can import mathop to get the typical operators as functions so that you do no longer need "expr".


Does that happen automatically in some cases? I think I'm on 8.6 and I'm pretty sure I forgot the expr and it worked OK. Could have been a string operation or something, I don't have the code to check on hand.


The string command accepts a special syntax for indices, which includes addition (but not the full power of expr) [1]. Maybe you are referring to this? Also, list commands accept the same syntax for list indices.

Example:

    % string index abc 1
    b
    % string index abc 1+1
    c
    % string index abc 1+1+1
    bad index "1+1+1": must be integer?[+-]integer? or end?[+-]integer?
    % string index abc end-1
    b
[1] http://www.tcl.tk/man/tcl8.6/TclCmd/string.htm#M54


Well, you don't need 'expr' in contexts were an expression is expected, e.g. 'if' 'while', 'for' (2nd arg).


I think that this is what I was experiencing.


Not a big deal, but it's generally "Tcl" these days, not TCL.


Unpopular opinon: I've used TCL and didn't like it and wouldn't recommend anyone use it.

The shell-like "everything is a string" is seductive at first but in practice you spend way too much time messing up your quoting. It's similar to how sometimes people suggest dropping yaml/json for a "simple ini file": it quickly breaks down and you end up with a custom ill-defined mechanism for nesting values.

TCL can handle more than just string variables: you have arrays, dicts and a bazillion libraries implementing object orientation. The result is that manipulating structured data is still more awkward than in any other modern language, except perhaps shell scripting.

Unless you're interfacing with a legacy or third-party system please don't use it. If you think you need expect please just use pexpect.


I'm not sure that's an unpopular opinion? Tcl has declined in use over the years, and while there's a vocal community of people who like it, I never got the impression that Tcl was popular nor that its popularity was increasing.


For a time in the 90s it was very popular. It was often paired with AOLserver for web applications. And it became a glue/scripting language for some heavyweight programs like EDA tools. I mean it was popular enough to somewhat ironically just pull it into the python standard library.


Yep, this is exactly how the company I used to work for used it (tcl/AOLServer) in order to create a web interface for managing paid-for network connections in hotels & what not.


> Tcl has declined in use over the years, and while there's a vocal community of people who like it,

To my way of thinking, Tcl is one of the languages that falls into the same category as Lisp, Smalltalk, and Forth. Like those three, Tcl takes a relatively smaller number of concepts compared to most other languages and tries to get more mileage out of combining them together than resorting to adding new conceptual layers. For Tcl, the core concepts strings and string manipulation. Most languages have these things, but very few languages build their list libraries, evaluators, etc. nearly as directly upon them as does Tcl.

The net result of this approach is a language that's almost guaranteed to feel strange for the vast majority of developers, who work in languages that tend to be composed of larger numbers of more specialized features. So immediately off-putting to large numbers of potential users.

The other property these languages share, once you get past the initial barriers to entry, is a certain sense of enablement and power. The first few times, you realize how control flow structures, etc. are easily implemented in terms of user-visible language constructs, it's at first gratifying and exciting to see and then potentially enabling. After all, it's easier to write a custom expression evaluator in Tcl than, say Java or Python.

So the community of opinion around these opinions tend to bifurcate along lines of whether or not the individual in question has spent enough time to truly 'grok' the nature of the language.

And note that this can be totally orthogonal to opinions on whether or not the language should actually be used. It's easily possible to not 'get' the nature of Tcl or Lisp and yet have it be the thing you have to write to program your EDA tool or AutoCad. Similarly, it's easily possible to see the power of a language like Tcl and lament either that too few people understand its full power or that it's full power is maybe too flexible to be used in a production setting on a large industrial project.

None of that means these languages are not worth pursuing, but I do think this line of thought helps explain how they succeed and fail in the marketplace of ideas.

> I never got the impression that Tcl was popular nor that its popularity was increasing.

Because it was developed as part of work on EDA tools, it developed a niche there. Also in early web via AOLserver.

Where it truly shown, however, was in GUI programming on Unix. Tcl and its GUI library Tk were around X11 before virtually anything other than the original Xt-derived widget libraries. Even more than that, you could open up an interactive 'wish' session and get an active and clickable button on the screen in literally three interactive commands. Compared in ease of use of almost anything other than Visual Basic, Tcl/Tk was light years ahead, and Tcl/TK far surpassed VB in expressivity. (For the reasons I mention above.) Between this and a few other libraries like 'expect', it's hard to overstate exactly how much power Tcl/Tk put in your hands, and relatively easy to use at that. To be honest, there are still large swaths of modern development where we've really regressed in expressive power. (Although HTML/JS does make it pretty easy to get a button on the screen in the simplest case.)


> The other property these languages share, once you get past the initial barriers to entry, is a certain sense of enablement and power.

That's the thing that Lisp/Smalltalk/Forth/Tcl proponents, who lament the unpopularity of their favorite language [1], frequently get wrong. It's not the case that others don't see the light and don't grok the power and flexibility that those languages bring, but that those don't really matter that much in most practical use cases, and that they're even detrimental to building and maintaining a large code base with multiple developers.

Yes, it's great that you can write your own control flow constructs. So what? A sane language already includes those constructs, and they're known and understood by all users of the language without having to first read the documentation of some third-party lib (haha, just kidding, there is none – read the code, dummy!).

[1] I don't mean to imply that you're one of them, I'm talking in general.


> That's the thing that Lisp/Smalltalk/Forth/Tcl proponents, who lament the unpopularity of their favorite language [1], frequently get wrong. ... but that those don't really matter that much in most practical use cases,

This statement does a good job of summarizing where I've landed on these sorts of languages, myself. Viewed in terms of Amdahl's law, the most you can improve a system by adjusting a single component is the impact of that single component. From a systems development point of view, the most impact you can have by changing programming language is to eliminate or reduce the cost of expressing your system's processes in a form the machine can understand.

Notably, this still leaves open most or all the other problems that beset software projects. The requirements are still under specified, the team is still subject to staffing constraints, funding still has to be justified and acquired, legal and business and scheduling constraints are all still there, and is the business viable at all in the timeline that you have? [1] The list goes on and on... and because the language doesn't really help, the value prop for niche languages goes way down.

That negativity aside, I do see potential counterarguments to this in the fact that an expressive enough language can help you improve your process to the point where you get answers faster and more reliably. But even that argument requires both a leap of faith and the willingness to take on the risks that implies.

1] Looking at this list, it's written in a way that might seem to imply startup/VC-funded project work - but that's not intentional. Those issues are also almost all faced by internal corporate development projects - either IT or for externally facing projects.

> [1] I don't mean to imply that you're one of them, I'm talking in general.

I didn't think you were, but thanks! :-)


> Yes, it's great that you can write your own control flow constructs. So what? A sane language already includes those constructs, and they're known and understood by all users of the language without having to first read the documentation of some third-party lib (haha, just kidding, there is none – read the code, dummy!).

I do not believe that novel control statements are any different from novel functionality. A sane language already includes plenty of standard functions, but that doesn't relieve the need for more. New functions, like new control statements, may be poorly documented.

The fundamental power of computing is abstraction. Functions, macros and control structures are all different types of abstraction. The only way to build a successful, malleable large program is to abstract, and to avoid macros and new control structures is simply to require larger teams (because someone has to hand-write all the code which the computer could be writing for you) and more ad hoc approaches.


> A sane language already includes plenty of standard functions, but that doesn't relieve the need for more.

The difference is that I write new functions on a daily basis, while I almost never need new control flow constructs. And if it turns out that such a construct would be useful, then it's almost always better to also have syntax and compiler support for it (for error checking, more descriptive parser errors, optimizations).


> The difference is that I write new functions on a daily basis, while I almost never need new control flow constructs.

I wonder if perhaps you only think you rarely need new control flow constructs because you are using languages without good support for macros.

Where a Lisp or Tcl programmer might just code up a true DSL (cf. CLOS or the condition system), perhaps you just write functions, never realising how much more readable and understandable your systems could be.


At least in my experience, macros are really an escape hatch of last resort, and for the reasons you mention. Semi-related: http://www.mschaef.com/defmacro-coupling


Ok, you don't often need to build your own control flow constructs, but it was exactly that capability that allowed the very successful Expect utility to be built on top of Tcl - https://en.wikipedia.org/wiki/Expect .


I tend to agree. I am just finishing up a tool I'm using to automate a bunch of interactions I have with the 4 USB UARTs on my desk and I ended up going with expect. If I knew about pexpect I would have probably used that.

However, since I did use expect and spent some time learning Tcl, I actually did appreciate one useful thing about it. It's very easy for me to in-line Tcl code into, say, a configuration, parse it with the help of `[info complete]`, attach it to a list and then expand that list `{*}$some_list` as an argument to `expect` or `interact`. I can now have UART specific macros that are bound to keystrokes like Ctrl-t x. Sure I could do something like that in python, but it probably wouldn't be as clear-cut as:

  # Fix terminal row/col height for less, vi, etc
  # type Ctrl-t r
  bind[r] = {
    # depends on xterm size info, may not be universal
    send "\{ "
    send {old=$(stty -g);}
    send {stty raw -echo min 0 time 5;}
    send {printf '\033[18t' > /dev/tty;}
    send {IFS=';t' read -r _ rows cols _ < /dev/tty;}
    send {stty "$old";}
    send {stty cols "$cols" rows "$rows";}
    send {unset old cols rows;}
    send {shopt -s checkwinsize;}
    send {clear;}
    send " \}\r"
  }


If you want to resize the remote terminal it might be easier to determine the size locally with an ioctl and only execute "stty cols/rows" remotely.

It might also help to export the local TERM value remotely because it's not otherwise passed through a serial port.


Thanks to you and the other comment under mine, I revised my snippet. I use to just copy/paste it into screen or tio, but now that I have this tool[1] I don't need to. You're absolutely right I could get the terminal size with tools like resize locally and I probably should set TERM to match.

[1] the tool if anyone is interested: https://gist.github.com/adedomin/7e615405a2275b01dbae3552116...


In a regular shell, would

eval 'resize'

Do the same thing?


That's not just a popular opinion, it might be the general consensus for the last 20+ years. That's why articles about people still using Tcl or even just people liking Tcl have so much novelty value. Tcl created a language niche that Perl/Python/Ruby quickly took over. It was all downhill for Tcl from that point on, for all the reasons you mentioned.

It was really cool for a little while though- I have fond memories of using it for a couple years in the mid '90s, but I would never go back to it once I moved on. Also, at the time I remember thinking Tk (Tcl's GUI toolkit) looked mostly modern and nice, maybe even more modern and nice than other GUI toolkits common on Unix systems at the time (Athena widgets, Motif, OpenView, etc.). As ancient and bizarre as it might look nowadays, back then it looked halfway decent if not outright OK. I don't know what Tk looks like now but I have to think it's not that different from 20+ years ago, with the weird autolayout/resizing policies and everything. Tk was a huge draw then but probably not so much now.


I suspect your experience with Tcl is a bit old. Tcl finally standardized on a single core OO library several years ago.

The quoting issues can be a pain, but if you learn to treat it like a language rather than extended shell, you learn the tricks to avoid escaping/quoting issues.


My experience with TCL is from scripting tools which picked it as an extension language many years ago. Tools like that have their own object-like systems and are likely not going to migrate, ever.

Maybe if TCL had a single standard OO library in the late 90s it would have been more successful? But I still think that languages with native OO constructs are much better that a shell-like string-oriented interpreter.


> The shell-like "everything is a string"

Exactly. Tcl is what we should be using for "shell scripts" instead of bash.


Unfortunately, pexpect does not do everything. I use this scheme to have keyboard shortcuts for devices on the other of serial ports.

  spawn -open [open /dev/ttyUSB0 w+]
  interact {
      `u {send "uname\n"}
      `v {send "show-version\n"}
      `` exit
      # lots more
  }

I have looked into it a couple of times, but I haven't been able to figure out the pexpect equivalent.


I think you haven't used it enough to appreciate its true value.


>...If, in order to "really" enter a programming culture, I need to both "be solving a significant real problem in the real world" and exercising "the freedom to change the language, the compiler, the OS or even the hardware design", then there are very few options for entering this culture indeed.

https://yosefk.com/blog/my-history-with-forth-stack-machines...


If you trust yosefk's judgement you might want to read his take on TCL: https://yosefk.com/blog/i-cant-believe-im-praising-tcl.html


"lovecraftian toolchain" is one of the greatest phrases I've ever heard and I use it all the time now to describe portions of the tech stack I'm exposed to at work.


Having not used Tcl since the 90s, I recently wrote some small graphical scripts in Tcl, basically tailing a text file, parsing the data, and producing a live animation[1]. The project was successful, but also reminded me about what I disliked about the language in 1994: As long as what you are doing is supported by the core language, it's "fine", but if you need to use an external library or need to do something beyond what the core does, it becomes quite tedious or even impossible. Also structured data is really badly handled. The article mentions defining your own operators and control flow, but is that something you ever really need? (Yes, occasionally, but not very often)

I believe now as then that the great contribution of Tcl was Tk (the graphical toolkit), which is fantastic and has bindings in other languages. I really wish GIMP had used Tk and improved it rather than inventing Gtk which is inferior in most ways.

Maybe this is all because I'm doing it wrong, writing scripts, and I should stick to its original purpose as an extension language, but it's easy enough to add C extensions to Lua or Python, and at some point you may end up writing a significant sized extension and the language will matter.

[1] http://git.annexia.org/?p=libguestfs-talks.git;a=tree;f=2019...


There is quite a wide range of extensions available, if you need to access an external library it's pretty straightforward to wrap it with Swig (https://wiki.tcl-lang.org/page/Swig), and creating new commands in C is also fairly easy, so I'm doubtful that there is much that's really impossible in Tcl :-)


It has been a long time since I fooled with Tcl, but in my recollection writing a function to call an external library wasn't that bad.


Where Tcl is nice is embedding the Tcl interpreter in a C main program. Lua also does this well.

This is the oft-overlooked embedding case which can be difficult in other languages (compared to the normal case where you start out in language X and need to call into a C function to do something low level). For example in Python the embedding case is tricky and lightly documented, and with only a semi-stable API which has changed under us a few times.

In nbdkit we do a lot of language embedding (https://github.com/libguestfs/nbdkit/tree/master/plugins) including Tcl, Lua, Python and many others.


The easiest way to think about Tcl is simply, "it's a Lisp, but with strings instead of lists."

It turns out that when you make a language like that, you end up something where your code looks and feels like a list of commands (much like a shell script) but is also capable of doing "real" programming stuff where needed without much pain.

The test suite for SQLite is (still!) written in Tcl, I think partly for this reason. You probably wouldn't want to write a test suite in bash, but you don't quite get that feeling of "it's just a list of commands."


My first job was a telco equipment manufacturer that needed to add a user-facing DSL to their embedded internet OS (the GenX iOS). I later used it with Expect to write a basic automated integration testing suite for the network equipment's CLI.

I really disliked TCL at first because the syntax seemed so arbitrary compared to other languages. It's only when you realize that TCL is actually more pure than other languages that you begin to appreciate its beauty. When the man page starts with "The following [12] rules define the syntax and semantics of the Tcl language:", they mean it. Those are the 12 rules. They are followed exactly and in order every time. Beyond those 12 rules, the rest is really DSL to make it look more like a normal programming language. It's very easy to code an entire TCL interpreter in 1000 lines of code. By coding in such a pure style, it made me appreciate how much the quirks of other languages are fundamentally designed to help programmers and not create frustration, which is how I always experienced all the "gotchas" I had to debug.


I was introduced to TCL/TK one summer when I was working at Sandia National Labs. I had been mostly doing C and ASM for the first part of my career, but the department I was contracted to was going through a dry spell in terms of funding so I got moved over to work with the GPS folks. I had never worked with TCL/TK before, and it was just such a guilty pleasure - you could slam out just about anything with it, in like no time. "Oh, you need to create a system with user-customizable dashboards for satellite telemetry? No problem, give me a few days..." I only worked with it for a few months, but it was some of the best fun I ever had writing code. I guess I feel the same way about react and node.js these days, but TCL/TK was ahead of its time.


I used Tcl (I didn't really used Tk), and I really liked how the language had no statements and everything was a function/procedure. I remember that in the past (I think currently not needed since now it is built in), you could implement yourself try-catch-finally and would work like rest of the language without feeling like it was hacked through use of macros.

Edit: Here it is: https://code.activestate.com/recipes/68396-try-catch-finally... not needed now since latest version has it built in.


upvar and uplevel were mind-blowing to me when I first learned tcl. It was relatively easy to derive new constructs that felt like part of the language.



Tcl is awesome, thank you for sharing this!

The design of Tcl is indeed simple and elegant. For example, check out the Tcl man page linked in the article:

https://www.tcl.tk/man/tcl8.6/TclCmd/Tcl.htm

The 12 stated rules suffice to define the syntax and semantics of the language.

And indeed, the Tcl/Tk tandem is great for building applications with convenient graphical user interfaces!


What clarity of thought! The article gets the point across in just a few concise paragraphs, wholly enjoyable. This is especially refreshing in an era where many similarly themed blog posts are 3-4 times bigger, and full of tangential and confusing rumblings.

Many thanks to the author!


While TCL is definitely an odd language, with plenty to alienate the modern programmer, there are some killer applications for it. For me the thing that sucked me in was tcl/expect a simple but powerful tool to control CLI's. At one point in my life I was tasked with managing over 3000 various network devices, I couldn't have done it without TCL/Expect!


What made Tcl click for me was thinking that it is basically shell/Bash, except that it's a coherent and sensible design. Just like an unix shell, everything is a string and you don't need to use "double" "quotes" "everywhere" "like" "this". However, in almost every part of the language, the way that Tcl does it is saner than the way the unix shell does it.

The infinitude of footguns of Unix shell make us discount it as a serious programming language but Tcl shows that it doesn't have to be that bad :)


TBF, half of the supposed footguns are people not understanding the difference between a command shell and a scripting language and trying to write code as if they were using the latter[1], and the other half are defects of specific shell languages rather than shell programming in general[0], but the lack of a decent implementation kind of hamstrings the latter defence.

0: There is no reason why a shell couldn't fix bugs like:

  $ echo "$X"
  *
  $ echo $X
  foo.txt bar.mp4
it's just that none of the common ones do.

1: especially the incessant stupidity about adding type information to pipes, as if grep were a function rather than the arbitrary binary file /bin/grep


The Plan 9 `rc` shell is a bit neater than typical Unix shells


I'm the blogger here - I think my main point is that the perceived oddness is inextricably linked to Tcl's strengths.


That's a great point, and after re-reading your blog-piece, I'm not sure that point came through so clearly as you just declared it here.

A LONG time ago, I used to use it (tcl/tk) to do quick-and-dirty apps on X-windowed Unix boxes and port them to Windows without really knowing much about Windows. (That was handy!)

And Expect blew me away back in the day of distributed systems management (I'm more of a programmer than a sys-admin, so I guess it would even be more important to those folks?).

The whole "There is no math, only strings" thing, still irritates me to this day, but I suspect you are right - this might be tied to the simplicity and strengths.

IDK. Food for though. Interesting piece. I think that I'm the only person I know that still dabbles in TCL after about 15~20 years ago (maybe I need to get out more), but it certainly rocks where it rocks! It is always surprising and pleasant to see a modern piece on it.


I think that goes for a lot of languages that are now often considered "odd". There is something about how an elegant and simple paradigm can help you think about a problem!

The first "higer" language I ever learned was Forth, and I never quite got to terms with infix notation, so I might be biassed ;)


If you want to automate stuff on windows with tcl, twapi is great. I prefer Tcl with twapi over AutoHotkey.


If someone asks me of a small snippet that describes some fundamental thing about TCL, I will respond with this:

    set a puts
    $a "Hello World"
A command is just a list. Substitution is done before executing it. That's why [set] requires the variable name, not $variable.


Python:

    a = print
    a("Hello World")
Rust:

    fn puts(s: &str) {
        println!("{}", s);
    }
    
    let a = puts;
    a("Hello World");
C++:

    #include <cstdio>

    auto a = puts;
    a("Hello World");
Also: every FP language ever. How is that a fundamental thing about TCL?

Also probably all shell scripting languages, like Bash:

    a=echo
    $a Hello World


The way I'm used to seeing the GP's example made is

    set a pu
    set b ts
    $a$b "Hello!"
which I think does a better job showing how the mixture of strings with interpolation allows for some slightly unexpected things.


Yes, you're probably right. Frankly, I'd rather not have this kind or error-prone behavior in my programming languages, not even when scripting. It makes proper handling of strings hard and cumbersome (as evidenced by a lot of software that can't handle spaces in file names because it's calling scripts written in sh or bash), and I don't get the Tcl love professed in the comments here.


I'm not a fan of Tcl -- I used it a bit in the 90's -- but this really isn't the best example. You need a bit more context to give it a fair shake.


This is kind of clumsy in R5RS Scheme:

    ((eval (string->symbol (string-append "dis" "play"))) "Hello world")


Good lord, as an example of why it's something we should want?

Each to their own of course, but..


I don't think this is the sort of code that people tend to write. But it does a good job of succinctly explaining how Tcl works.


For example because it's kind of homoiconic. Since everything is a string you can define your own control flow constructs for example...


If you define your own, say, repeat-until loop, can you use the built-in break and continue commands? Could you define a break-with-value command for the built-in loops?


Using Tcl exceptions, I guess it would be pretty trivial to do that.

Here [1] is an alternative do..while loop implementation provided by Tcllib, written in pure Tcl.

[1] https://core.tcl-lang.org/tcllib/artifact/4f7e97706ff67a40


Would it be fair to call this a kind of "pervasive eval"?


you've misspelled "evil" ;)


in TeX:

\def\a{mess}\def\b{age}\csname \a\b \endcsname {Hello there}\bye

in (UCB)LOGO:

? run list word "pri "nt [Hello there]


Because if you say a = "puts" in the other langs it wouldn't work. The other languages are assigning a function to a variable. Tcl is assigning a string to a variable, then evaluating the string as a function based on syntax.


Now do the same thing with 'if' and 'while'. In Tcl, you can define your own do...while loop.


In your examples, you need "types" to understand the code. In the parent TCL example, there is no type, thus, way simpler. Programming is a process, not just code and result. TCL process is way simpler.


If you use quoted strings in both lines, your intent will be more clear.

   set a "puts"
   $a "Hello World".
On the other hand, I have not used Tcl since the last time I run a Verilog on AIX (21 years ago). I don't miss it.


For those who are web-devs, I'd highly recommend you take a look at Wapp - A Web-Application Framework for TCL [0] by D. Richard Hipp (of SQLite fame). It's simple enough to start with and the source code is a great intro to TCL.

[0] https://wapp.tcl.tk/home/doc/trunk/README.md


Here's a fun little quirk in TCL that cost me about a day of debugging. An unmatched bracket in a comment, depending on the placement, can cause an error. :)

https://wiki.tcl-lang.org/page/Why+can+I+not+place+unmatched...


If you work or plan to work in the semiconductor industry with EDA tools (Electronic Design Automation) then Tcl is very popular because it is the built in scripting language for many tools from Cadence and Synopsys. Many companies end up basing a lot of their internal CAD flow on Tcl because it fits together well as wrappers for the commercial software.


For your future work:

If someone with 40+ years experience in the industry or gray/white/no hair says something about a technology trust him/her, after 8 month you can agree or not...but the chance is really high you will. And the big joke, old people are not IN because they never heard of "Ruby on Rails", but they already had experience with something like it, and in the long run it just don't work.


Here's a fun feature of tcl.

  set a "pu"
  set b "ts"
  $a$b "Hello World"
  ---> Hello World
 
In Python terms, this would be as if Python could do:

  a = "pr"
  b = "int"
  a+b "Hello World"
  ---> Hello World
Who needs eval?


And if anyone didn’t know already this is the behavior of every shell as well. Resolving variables to values is done before the line is executed.


Reminds me of foxpro macros


My only experience with tcl is through tkinter but out of all the GUIs I've ever written code in, it's the one I prefer. Strange way to learn a language, that. The only complete documentation is on the tcl side of things, so you have to switch between partial docs on the python.org site, partial (and opinionated) docs elsewhere, the only good site is now defunct, and so yeah, if you are determined to figure out tkinter you have to rely on docs in another language and then just -- I don't know how to say this, do the obvious thing, whatever seems most pythonic, most lazy, that is basically how it is intended to be used. Case in point: The way you that you hook up a stringvar to a listbox -- to have multiple items, you just ... set the string to a list. Or put newlines in the string. Simple stuff like that, or the ease with which you can make a simple interface with buttons whose command doesn't have to live in three different locations, you can just write a lambda and be done... but wait! That's how you're supposed to do it? It's not breaking rules? My curiosity about this tcl thing has been growing over the years, and I think this article has given me the push to actually try it on its own.


It's really nice that you can make an application with a GUI that runs on Linux and that you can also make it into an executable for Windows using Freewrap.


Sure, but that can be done in C++/Java/Python too. The real question is about the merit of the Tcl language.


Your executable will only be about 8MB plus the size of your source code. You definitely can't do that with Java; probably can't do it with Python either.


The biggest gripe I have with modern (ie. the post-Sun era) Tcl is the steaming mess that are channels and their encodings. Good luck trying to do anything 8-bit clean with those.

For a simpler, cleaner alternative, you might want to take a look at antirez's jim tcl


I have the exact opposite experience WRT Tcl channels when compared to other languages.

Handling binary data is pretty trivial, e.g. to read a full binary file into a binary string, you do:

  set h [open "filename.bin" r]
  fconfigure $h -encoding binary -translation binary
  set data [read $h]
Then you even have a fantastic way to operate on low-level binary data of any endianness using Tcl's binary scan /binary format instructions [1] (basically what Javascript later invented as DataView).

Tcl was one of the first languages I knew that properly and consistently supported multibyte text throughout the full language, including in Tk GUIs. I.e. writing a cross-platform GUI that could handle Japanese character input/output basically "just worked". You could even read ShiftJIS or ISO encodings of japanese text, which was at the time a prerequisite as Japanese Windows versions were non-unicode (everything done in ShiftJIS AFAIR).

[edit] here is a real-world example of a trivial script handling binary data [2]: reading binary RGBA 4 bytes/pixel image data and outputting RGB 3b/pixel into a pipe that finally outputs a .PNG image. It's difficult to find a programming language that can do that in less lines and with more clarity.

[1] https://wiki.tcl-lang.org/page/binary+scan

[2] https://stech.muecke.pw/opensvn/free/trunk/dkbin/nn-fbtopng


Yes, I see your point. I can't remember the context that bit me anymore, but I think it had to with being unable to change the defaults with fconfigure for some reason, the channel being implicit or somesuch .


I got curious, so here's a link to Jim Tcl:

http://jim.tcl.tk/index.html/doc/www/www/


I love TCL, but using it since 7.6. Although now it is mainly for personal scripts and developing proof of concept scripts for work.

If fact in 1999 I used TCL (and Expect) on an ISP I worked for to run various tests checking for Year 2K issues and we used the same framework for patching and system building. Talked to somebody I worked with at that place recently, he had found a bit of the old application, and we noticed we have a pretty good Ansible base written in it.

I also use it to write fairly easy DSL languages for various things, package them as tclkits, and have binaries that can be run on various machines.


I wish I had an excuse to really learn TCL. I've used it here and there but have never had an excuse to dive deep.


I think the core ideas behind TCL are so simple and self-consistent that getting "deep" isn't required so much.

Instead it's just a case of using it. In the past I used TCL for "expect" and for the Tk graphical toolkit. I can't say I've written anything major in TCL, but I think that's a common-case. Most people use TCL because it is embedded in applications as a scripting language/DSL.

When people express interest in TCL I usually point them at antirez's simple writeup which gets a lot of the basics shown of in a simple manner:

http://antirez.com/articoli/tclmisunderstood.html


I think it really makes sense if you want an interactive shell. In contrast to most other languages, you need no parens or other fancy sigils for normal commands.

A classic use case is a debugger like gdb. What else, though?


I haven't written any Tcl in years but one of the things I liked about it was that it's not deep at all. Very simple rules, with enough flexibility built-in to (usually) make it do what you want.


I want to get to the point where I'm comfortable using what makes Tcl special like uplevel/upvar. I can use it as a basic scripting language but I don't really grok what makes it special.

Its like knowing how to use lisp but not knowing how macros work. Funnily enough this is actually where I am now with lisp.


Sounds like the Forth philosophy.


In the Lisp world one often hears disdain for strings, and advice to get one's data in to some other representation so that it's safer, more expressive, and easier to work with.

Coming from that background, it's interesting to hear of TCL (which I do not personally know how to program in) embracing strings.

It would be interesting to read an article that goes in to some depth about the sorts of useful things that TCL's focus on strings makes possible or easy that would be difficult or unnatural to do in other languages.


If you like the "Unix Way" idea that programs should be able to handle input and output in a high-level string representation so that it is trivial to share data among a multitude of independently written programs, then you'll love Tcl.

Tcl not only allows you to share string representations of data between different programs, but also internally between different modules of the same program, easing issues of interoperability, scalability and deployability in wildly different systems and environments.


"Tcl not only allows you to share string representations of data between different programs, but also internally between different modules of the same program, easing issues of interoperability, scalability and deployability in wildly different systems and environments"

So how does that differ from just passing around a JSON blob or something?


JSON is a typed data format, where details of formatting and interpretation of types is left to the implementation. If you're not using Javascript, encoding and extracting the type information can be tricky unless you know the source well and understand the type formalisms it uses. Thus JSON isn't as handy as a universal data exchange format.


I'm still trying to wrap my head around what you're getting at... is it closer, then, to XML with an XML schema?


There is no schema!


Tcl hasn't been string focused since 8.0 was released 20 years ago. Tcl objects are convertible to and from strings. That conversion can be deferred so a string representation hangs around but it still only uses strings as needed. Nobody says Lisp is string based because everything can be printed as an s-expr.


Umm, sorry, no.

First of all, lisp sexps have nothing to do with strings (which is why noone says that), whereas in tcl, every data structure has something to do with strings.

In tcl, semantically, everything is a string. Yes, the native internal representations of compound structures like lists and dicts are actually very efficient, but you can refer to those structures as if they were a string at any point.

And that will often cause the internal representation to switch to a string, and dump the more efficient "native" rep aside.

And that can happen when you don't really intend for it to happen (the infamouse "shimmering" problem).

Thats the biggest flaw I've found in years of hacking with tcl. It makes it hard to write funcs which take polymorphic data types. Is this a list of lists (where each sublist contains strings) or a list of strings (where each string may have whitespace)

You end up creating your own dynamic typing system sometimes. I know I have, and so have others (see the wiki).

There is SO much to love about tcl. It really is a lisp smashed into shell. And its so dynamic that you can do really powerful things in it.

Its really a lisp,, where the standard data structure is the string, not a linked list. And any func can be an f-expr (basically, sort of a runtime macro, which older lisps used to have).

I had a lot of fun redoing things like quasiquote (from lisp) in tcl. Yes, you really can generate tcl code as a template rather than manipulating strings.

Combine some sort of diy tagging system with ensembles (so that your code will run specialised funcs all automatically chosen based on your initial tag name).

The OO system is basically a toolbox for building any kind of OO system you want on top of it (almost akin to CLOS-inspired systems, in that regard)

Stackable io channels so that you can build a virtual filesystem with a various features all composed together (FUSE-like done beautifully, from a scripting lang perspective)

Great stuff. It really is a lisp/shell kind of thing, but sometimes its so dynamic that it shoots itself in the foot (shimmering, etc).

I wish they had decided to dump backwards compatibility post 8.0, and tried addressing some of horrible warts in the language and runtime, eg:

- the syntax rules are simple, but result in non-trivial code looking F UGLY (emphasis on the F). A couple of extensions to that syntax would have made the world of difference. How much more complicated would, say, 15 syntax rules be instead of 12?

- shimmering. NO. Stop it.

- not everything makes sense as a string rep (filehandles?)

- the standard commandset (really each is a DSL in its own right) needed to be revised long ago so that they were more consistent with each other (contrast list cmds with others)

Basically, maintaining backwards compatibility has killed tcl, even though it has so many nice features and potential greatness hidden inside.

(eg: jimtcl, a hidden gem)

Ok, I'm ranting now, I'll stop :-)


I've been a TCL fan since the mid 1990's. We used TCL as our web server / scripting setup. We were able to attach to our IBM mainframe and deliver custom pages to all of our customers.

TCL is still the fastest way for me to make scripts. And as someone else posted, EXPECT was a great tool for testing applications and doing some basic automation. I laugh when the new consultants go "Robot Process Automation" RPA is the wave of the future, I've been doing that for two decades.


I used Tcl by virtue of a software package in the scientific domain I work in called OOMMF which is old but a stalwart and very reliable. I find it an odd language.

But the one thing that I think is very cool, is that it's very very simple to get a minimal Tcl interpreter (partcl) that can be embedded into a C/C++ application. It also still comes bundled in to Python for the Tkinter framework. You can even use it in Jupyter Notebooks now


I've found TCL to be pretty pleasant on Windows. It is pretty simple and I love building procedures that can be run as commands as it models my thought process better. I like that it is tiny, but very powerful behind the scenes with some very neat features.


Tcl has saved my work in the past. I could create very quickly GUI command line programs for my reasearch. Now that I am exposed a bit to Lisp, I wish Tcl also supported a Lisp syntax too.

In any case a very powerful language that is easy to learn and use.


Had a look into it due to work and I don‘t like it. Code was hard to read and badly organized. I can‘t remember if it was the languages fault.

Wanted to add a testing framework to refactor code. Didn‘t find something good though.


A lot of people write Tcl as if it were C or Bash without understanding the language or its philosophy. That, unfortunately, leads to badly written code like that you've seen


I'm intrigued by Starpack/StarKit, the virtual file system and virtual time. Never used Tcl, so far, but I'm thinking about sacrificing a weekend to playing with it.


Tcl is amazing just for Tk's Canvas alone. All other sins are forgiven.

I've never found something that easy to use. Tkinter (Tk through Python) is awesome.

Since this is HN, if somebody knows a scene graph canvas that's even better and as easy to use, please let me know. I'm primarily interested in EDA (so not games).


Awesome.. gitk is written with Tcl too. More details: final title of https://medium.com/swlh/impressive-sources-codes-that-every-...


I really enjoy Tcl. I just do. It's hard to explain. I like the quirkiness. I like the community. I watch the emails on the core developers list and all the thought that goes into it.


I worked on an embedded linux project years ago and perl or python would not work/fit. But tcl would and did.


For me, Tcl was always just "that thing you had to learn to script your eggdrop" and I always found the esoteric nature of Tcl to be at odds with its claims of being a silent, behind-the-scenes enabler embedded into thousands of products. I suppose I have no reason to doubt the website, but was Tcl really as widespread as claimed?

And is there any reason to reach for Tcl today when lua and guile exist?


Tcl is at the core of F5 (bigip)[0] and A10[1] network edge devices, tea leaf traffic monitoring [2], gnu gcc test suite[3], big finance tools[4], and very large computer management [5], for starters. One could go on with examples of industrial and scientific controls, Hollywood gfx, and EDA (electronic design automation) that may have contributed to the design of whatever device you’re reading this with, etc, but it’d be a long list.

It’s battle-hardened, which is important, but it’s also fun, which is important too.

[0] https://devcentral.f5.com/s/articles/irules-concepts-tcl-the...

[1] https://www.a10networks.com/blog/aflex-tutorial/

[2] http://www-01.ibm.com/software/info/tealeaf/

[3] https://en.wikipedia.org/wiki/DejaGnu

[4] https://www.fidessa.com/products/training/training-courses

[5] https://www.mcs.anl.gov/~wozniak/papers/Swift_Tcl_slides_201...


Creating iRules for F5 BigIP has been my only experience using TCL and that in itself turned me off of it which really isn't fair because having to create complex iRules would have turned me off whatever language they might have been implemented in. Also to be fair if you are implementing complex iRules you are doing something wrong but sometimes fixing things where they should be is beyond your control.

Speaking of lesser used languages still used for specific domains, is REXX still used commonly for voice response systems? It was last time I had to deal with one around 2006.


Haha, I was going to write the same. Writing iRules for F5 BigIp has made me hate Tcl, but honestly I'm not sure the real culprit isn't BigIp's terrible, clunky UI.

I don't know why they chose such a brittle, error prone language for writing something where making a mistake can have dire consequences.

(I see someone else mentioned Tcl is used for Nuclear Power Plant simulators? Ouch!)


Nuclear power plant management... [0]

Embedded medical device software ... [1]

i.e., when the consequences of failure are just too great, a lot of people don't dare pass up Tcl.

[0] https://wiki.tcl-lang.org/page/COMPANY%3A+KKG

[1] https://www.incubelabs.com/


It was the visualization of the simulator... consequence of failure doesnt seem too great. Btw how does tcl allocate memory? (So is it real time compliant?)


Note the bottom of the linked page where the author says they use Tcl/Tk for all their interfaces.

Also interesting that you think flaws in the tool you use to learn to run a nuclear power plant are no big deal.


I use it a lot with FPGA vendor tools.


How about lets move to jsonnet and call it a day




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

Search: