Hacker News new | ask | show | jobs
by simon 5258 days ago
The article seemed a little short for me, but then I am actively trying to select between Lua and TCL for some personal scripting projects. There are many fine features with each language and few downsides, so the selection process is hard. Of course, that's a nice problem to have.

TCL is ahead by a nose at this point with Unicode support baked in (vs. using a library) and file system handling built in (again vs. using a library).

4 comments

Tcl is an interesting little language as well, and the niche it was created for is similar to the one Lua was created for. The biggest advantages that Lua has over Tcl, off the top of my head, are speed and lambdas. Tcl's semantics make it very hard to optimize because it is stringly typed (with some bytecode and value specialization in the background, but with conversions between strings and other values as needed).

Tcl's file system interface is definitely an advantage if you're trying to avoid third party libraries. However, depending on what you need to do with Unicode strings, Lua's strings are "8-bit clean" and have no difficulty storing Unicode characters; Lua's string functions (the pattern-matching functions in particular) aren't Unicode aware.

Tcl has lambdas (anonymous functions): http://wiki.tcl.tk/4884. As of 8.6 (currently in beta), it also has coroutines, and has a non-recursive engine (stackless) among other niceties.
Shows how long it's been since I last used Tcl!

Still, Tcl's anonymous functions aren't quite what many people consider to be lambdas:

    % set inc {x {expr $x + 1}}
    % apply $inc 1
    2
    % apply $inc 1
    2
    % $inc 1
    invalid command name "x {expr $x + 1}"
    % inc 1
    1
This works fine with `apply`, but if you treat it like a normal function, it does some strange things. Conversely, functions that are defined with `proc` aren't compatible with `apply` unless you wrap them up.

I'm not saying it's inadequate, just that the anonymous functions don't quite work how you expect lambdas to work.

I can't speak to what most people expect from lambdas; I force myself use Tcl's [apply] occasionally just to try slightly different paradigms, so I appreciate your commentary.

One thing to note though, your final [inc 1] has nothing to do w/ $inc. In the interactive REPL (which I'm assuming you used), Tcl will (by default) essentially autocomplete commands if it can, and [inc] completed to [incr], which is "increment". [incr] adds (by default) 1 to the named variable and returns its result. In this case, the variable name happens to be "1", later accessible via "$1", or [set 1], for example.

[edit: I erroneously initially described the "1" in [incr 1] as the integer constant 1; @groovy2shoes reply below reflects my original error. This does go to show another neat feature of Tcl: no keywords.]

I didn't know that tclsh autocompletes commands; that's pretty neat. In this case, it looks like [incr 1] is incrementing a variable called 1, and appears to start from zero if the variable isn't initialized.

I find Tcl's command model interesting because it leads to a very tiny semantics. A few years ago I spent a lot of time thinking about how it could be extended to have lambdas, and I couldn't come up with a way that wouldn't break the command model in some way or another. They aren't something Tcl needs to have, I just thought it'd be convenient. (Tcl's evaluation model allows you to simulate higher-order procs, which, along with `apply`, covers many use cases of lambda).

Ya -- interactive tclsh has a few creature-features. The autocomplete we're discussing, automatic fall-through to exec as if via sh(1), command history, history editing, and perhaps more I'm forgetting.

  kamloops$ tclsh8.6
  % info commands up*
  update uplevel upvar
  % uptime
   7:17PM  up 1 hr, 7 users, load averages: 0.06, 0.12, 0.17
  % ls fu
  ls: fu: No such file or directory
  child process exited abnormally
  % ls -ld fu 
  ls: fu: No such file or directory
  child process exited abnormally
  % ^fu^foo
  ls -ld foo
  -rwxr-xr-x  1 joe  users  7300 Mar 23  2011 foo
  % history 
     1  info commands up*
     2  uptime
     3  ls fu
     4  ls -ld fu
     5  ls -ld foo
     6  history
  % !2
  uptime
   7:20PM  up  1:03, 7 users, load averages: 0.13, 0.12, 0.16
@groovy2shoes (and anybody else who's interested in modern (or historic, for that matter) Tcl), you should drop by #tcl on irc.freenode.net. We'd love to have you visit.
To my point of no keywords, and touching on the interesting model @groovy2shoes is talking about here[1]:

  $ tclsh

  % set a set
  set
  % puts $a
  set
  % $a b 9
  9
  % set b
  9
  % set set set
  set
  % $set set
  set
  % rename set foo
  % foo set
  set
  % foo a
  set
  % foo a 9
  9
  % puts $a
  9
  %
[1] http://news.ycombinator.com/item?id=3536419

[edit: formatting]

More good points for both sides. This is not making it easier.

I don't need speed as I'm doing offline processing and not worried about lambdas at this point. The unicode is important as I am looking to take Greek and Hebrew text and process it.

You may be better off with Tcl, then, if you don't want to use a library for Unicode.
It's not so much that I don't want to use a library, but more that I would be unable to use much of the core language for the processing and would have to do everything in/with the library and store my text in Unicode-aware holders rather than just strings.

If that's how it ends up, then so be it, but I'll try TCL first and know that I have Lua as a reasonable fall back plan.

If you're considering TCL, the Jim implementation might also be worth a look. It has most of the features of the core language, some extensions to enable even more and a very small footprint. If I recall correctly, it's even faster for some things and does lambdas etc. a bit better.

The bad thing about Tcl is probably its library support. It has an extension mechanism, but for a lot of "contemporary" projects (web etc.), you're actually more likely to find working Lua "Rocks" than tcl modules.

jim: http://jim.tcl.tk/

Interesting, thank you. I will take a look.
I suggest you to use Tcl, and I think I'm not biased since for instance the Redis unit test is written in Tcl but I'm using Lua as scripting language for Redis.

But as a language, Tcl will allow you to experiment a completely different way of thinking. Lua is neat but not so different from what you already know.

not often mentioned: tcl's slave interpreter, and command redirections from a slave interpreter to its master. a master interpreter can hold many slaves interps, and any slave can be a safe interpreter not execing anything that might be dangerous. redirecting, by renaming, a slave/safe interps commands the master will know. tcl's threading model (if needed): sending messages, one thread per interpreter, and one thread can have multiple interpreters. tcl-8.6 has a killer object model. tcl's vfs, and starkit/metakit makes distribution simpler.

what i do not use tcl for is: web. unfortunate lack of a framework.

it has good support for downloading stuff, ftp, http, bignums and algorithms if needed.