Hacker News new | past | comments | ask | show | jobs | submit login

I actually was forced to use Tcl recently on a project, and I came across this article at the time.

It so happens that I was getting into Lisp at the same time, and the parallels between them are obvious. You effectively get macros, so it's a pretty expressive language. There's even an object system in Tcl based on CLOS. But ultimately, it feels like a language with lots of good ideas, implemented poorly. I'm not a PL theorist or purist, but "everything is a string" constantly feels like a really poor abstraction.

Tcl is practical for small, quick projects, but you soon run into insane things like the fact that curly brackets are syntactically significant in strings - and comments.




I actually wrote some code to find unbalanced braces in the codebase I was maintaining at work. One big downside of Tcl is that the parser gives you practically no help with syntax errors--never a line number, and only sometimes does it give you context.

Another common mistake is that curly brackets are VERY significant in [expr]. The author writes statements like "expr $i * $i" in several places, and it makes me cringe for two reasons:

1- This code prints "5" because expr does a double-substitution:

  set a 5
  set b {$a}
  puts [expr $b*1+0]

What's going on here is that $b is evaluated (to the string "$a") before calling expr, then expr itself evaluates its argument:

   $a*1+0
to 5. This is a problem because $b can be anything--for example, a call to [eval] arbitrary code.

2- Calling expr without putting braces around the argument is unfathomably slow. Tcl precompiles procedures as much as possible, and calls to functions requiring dynamic evaluation (like eval or expr without braces) can't be precompiled.

I once solved a huge performance problem by finding and fixing calls to expr made without braces. What was a process that took 40+ hours to finish was reduced to around 45 minutes by this change alone.

edit: formatting


I am working on a Tcl parser implemented in Python as a side project. Feel free to use it on your code base:

https://bitbucket.org/ul5255/code-snippets/src/61958ee922cee...


Why do I see people talking about this kind of thing in Tcl being perfectly okay, while PHP is nowhere near as randomly dynamic and gets a lot of hate?


I suspect for two reasons - first, that Tcl is always dynamic the same way and in clearly documented places, whereas PHP is a lot less consistent about it; and second, that in Tcl a lot of the core language constructs do so, so it's something you get familiarised with early rather than bitten by later.

Plus, PHP users seem to be most likely to either go "err, so?" or "YOU DON'T UNDERSTAND THE TRUE GLORY OF PHP!!!" in response to being asked about it, whereas Tcl users generally tend to respond "yeah, you need to learn about that and get used to it" - which tends to significantly alter the next comment made.

(not trying to imply that PHP doesn't have users in the third category, just that the first two are the more visible and it alters the discussion's tone)


Probably because Tcl has other redeeming qualities.

Command line programs are now passe in all except a few niches like routers, chip design etc, but IMHO there still isn't a better "/bin/sh++" that you can embed as command line shell interface between your C functions and the user.

Swig + Tcl + C/C++ works like a dream!


Lua?


I would make a distinction between a CLI (to be used by ordinary users of the program) and a scripting interface (to be used to "extend" the program, to be used by power users and/or other programmers).

And I would further submit that the same language may not be the right choice for both tasks.

Tcl leans further towards being a pleasant CLI interface language, while AFAIK Lua leans further towards being a pleasant plugin development language.

IMHO.


tclsh is a REPL (Read/Eval/Print Loop) coded against libtcl. libtcl is _easily_ integrated into any C (C++) development project. tclsh is but one.


> curly brackets are syntactically significant in strings - and comments.

The latter trips me up far more than I would like to admit :(

It's a great example of the nature of Tcl as a language, though. Sometimes I love the simplicity, sometimes consequences of it drive me nuts.

For those who haven't used Tcl: You write comments like this:

    # this is a comment
But, in keeping with Tcl's simple and tiny nature, this isn't a special case. "#" is simply a procedure that ignores all arguments supplied to it!

While this is extremely elegant, and means you could implement comments in Tcl itself rather than the interpreter, it does mean that you have to balance your curly brackets within comments, which is hugely annoying when you forget.


I use Tcl for a number of analysis scripts inside some scientific software. Recently, I came across a situation in which I had nested loops:

    for {set i 0} {$i<$n} {incr i} {
        # Some comment
        for {set j 0} {$j<$n} {incr j} {
The script refused to run and eventually I figured out that the comment was somehow impeding execution. I still don't understand why.


This also breaks, because comments are syntax.

   proc some_proc {a b} {
   
   } # some_proc


Based on the instructions in the article (tho I haven't tried it out), putting a semicolon before the hash would work...

    proc some_proc {a b} {
    
    } ;# some_proc


That's easier to explain though - you are passing the arguments {a b} { } # and some_proc to the procedure some_proc. Because comments are just another command, the # has to be the first non-whitespace character on the line.


Are you sure the comment didn't have some curly brackets in it or something like that?


To my best knowledge, the hash mark comments are parsed as comments by the Tcl parser. The interpreter will not execute a "hash mark" procedure. You can check for the parsing and semantics of Tcl by googling for "Tcl dodekalogue".


> But ultimately, it feels like a language with lots of good ideas, implemented poorly. I'm not a PL theorist or purist, but "everything is a string" constantly feels like a really poor abstraction.

I see where you're coming from, but IMHO:

Tcl's ideas make total sense if you understand why the language was invented. The name is the hint: Tool Command Language. It was never intended to be a "proper" programming language, AFAIK.

That is, a "sh++" CLI to be embedded in big programs. The role of the CLI is to be a thin layer between the data structures in the embedding program and the user.

The EIAS approach makes it easy to write commandline scripts. I've seen non-programmers abuse the hell out Tcl but the underlying C function still got the correct arguments.


You can also write your own object system in like half a day, I think you peeked, but didn't completely open the door.




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

Search: