Ruby vs Tcl, part 1

Posted by David N. Welton Mon, 06 Mar 2006 14:25:00 GMT

(Note: as of 06-04-14, "Round 2" is now available: http://journal.dedasys.com/articles/2006/04/12/ruby-vs-tcl-round-2)

Actually, "Ruby vs Tcl" is just a dramatic title. I like to think of myself as somewhat of a connoisseur of programming languages, which means I find something to like about most of them. Also, having put my toes in the water by creating my own, Hecl, I have way too much respect for the people that do the work to really pick on any language too much. However, comparing and contrasting is fun, as long as it stays productive!

I'm a long time Tcl fan, having known the language for something like 7 or 8 years. Recently, I've started picking up Ruby, because I've decided to follow the herd and use Rails (which is every bit as pleasant as its made out to be, but more on that another time).

Where Ruby shines

Coming from Tcl, which has to be one of the most misunderstood languages out there, one of the things that I enjoy most about Ruby is all the buzz. It's a pleasant change from the "trying to hold the line" mentality in the Tcl world. Of course, marketing and the inclinations of 'the herd' are fickle things, and as the Python folks are discovering, what popularity giveth, popularity can take away. In any case, learning a new language is fun and not all that difficult with Ruby, so I'm enjoying riding the wave. Point in Ruby's favor, even though sometimes I'm left scratching my head that it took Rails to convince some of the Java guys that scripting languages really are that much more productive.

The other thing that really sticks out about Ruby compared to Tcl is that it's Object Oriented (henceforth known as 'OO') through and through. At the low level, I don't really care too much (puts "hello world" is valid Ruby and valid Tcl), but Ruby's OO is nice for organizing more complex data structures. Tcl has OO as well. Actually, Tcl has several, competing OO systems, which is a classic case of "choice is not good" because none of them is standard and something you can count on being present. Also, most of the Tcl object systems don't do a great job of deleting unused objects. I don't suppose it would be that hard to add that if there were one good, standard one. Luckily, such a beast is on the horizon, but it's awfully late for a language that's more than 15 years old. Point goes to Ruby.

Ruby also wins in the 'available libraries' department, although probably not by that much, being relatively new to popularity. What Ruby really has going for it is that:

1) The standard distribution is pretty big, with lots of good stuff, an approach that the Tcl world hasn't taken. This means that Ruby out of the box does a lot more than Tcl.

2) Via Ruby Forge and the gems system, Ruby is attempting to centralize and standardize the distribution of extras, something which Tcl has never really managed.

Things they both do well

In terms of community, both languages seem pretty well off. The Tcl newsgroup, comp.lang.tcl, is one of the friendliest, most helpful corners of usenet, and reflects very positively on Tcl. I'm newer to Ruby, but by and large, they seem to be handling the massive influx of new people with aplomb, and without much, if any, of the snotty "I was here way before you" attitude that sometimes crops up in these cases. I'd call it a tie.

Both languages are very flexible, but in different ways. They both support 'eval', and let you do all kinds of nifty introspection. I fear I don't know Ruby well enough to come up with a definitive answer, but I Think I'd still give the edge to Tcl, just because of its ultra-simple syntax and command-based style lets you redefine Tcl commands in Tcl itself - and everything is a command, even if, while, and the lot. Like I said though, this is a vague enough requirement, and they are both very malleable languages that you could make a case for "everyone being a winner".

In terms of syntax, de gustibus non disputandum est. Ruby has more of it, which can sometimes be helpful. For instance, foo[1] vs lindex $foo 1. On the other hand, Tcl's

array set hash {
    foo bar
    bee bop
}

Makes me reach for the shift key significantly less than

hash = { :foo => "bar", :bee => "bop" }

Tcl's spare syntax is one of the reasons it is so flexible, but for everyday use, sometimes it's nice to have a little bit more. In the end, it's a question of taste, so we'll call it even.

Where Tcl is rock solid

Here's where the "part 1" in the title comes in. The following are things I don't care for in Ruby, but since I'm new to it, there's the chance that I'm missing something in these observations.

Interpreters. Tcl lets you handle multiple interpreters not only at the C API level, but in Tcl itself. This is really cool - you can juggle different people running different scripts in your application, without them stepping on one another's feet. If you want, you can let them share stuff, too. This capability has also been extended to provide safe interpreters for the execution of untrusted code. Ruby has safe evaluation too, but it's not in a completely separate context, so it's just a different way of doing things, but still, I like the idea of having and being able to manipulate multiple interpreters. Tcl wins hands down.

Event oriented programming. Tcl really shines here, as it's possible to create simple, fast servers without actually having to muck about with select yourself. The python folks have caught on to this with Twisted, and I suspect that Ruby will too, if it hasn't already and I'm simply not aware of it. Note that Ruby has a select call as part of the language, but what I'm talking about is being able to whip up servers in a few lines, without even needing to require any external modules.

Modularity is an area where both languages could do better (well, at least for some users/uses). Both languages might be interesting in the embedded arena, but it takes some effort to cut them down to size. In Ruby on the Mobile, Matz himself states that this isn't an easy operation. Tcl is notable in that it has some small footprint implementations like Jim, but the core language would require non-trivial hacking to remove some of the bits and pieces that are 'welded on'.

A few nitpicks about Ruby: no deep copy - you have to marshal/unmarshal, which feels wonky to me. File.split functionality is just dirname/basename rehashed, rather that Tcl's more correct/useful splitting of a path into a list of all its components based on the current platform's directory separator.

Threads are another area where Ruby, at first glance, at least, could probably use some work. Tcl has real, OS-level threads, which are very easy to work with because each one gets its own interpreter. Because of this, they almost feel like separate processes, but of course, if you need to, you can do all the sharing and mutexing and so on that you need.

Conclusions

So, what conclusions can you draw from this? Well, they're both fine languages, and are more than likely capable of doing most anything you need. Something else that I was pleasantly surprised by is the fact that Tcl, despite its age, and its lack of buzz and O'Reilly/Web 2.0/the hot new thingness, still has a lot to show the world, and does a lot of things right, out of the box. It's also worth noting that most of the problem areas for Tcl are social, rather than technical, and could have been resolved easily/avoided with the right leadership.

6 comments |

Trackbacks

Use the following link to trackback from your own site:
http://journal.dedasys.com/trackbacks?article_id=96

  1. gabriele
    about 19 hours later:
    I think that Tk has an advantage in the distribution/packaging side, due to versioned packaging being standard and due to the whole tclkit/starkit thing. And I'm always puzzled by the fact that some problems arose wrt rubygems were probably already faced by tclers but nobody thought of looking there (maybe people did, and I'm just unaware of that) And about OS threads.. it seem that we could be able to use them in rubyland once YARV is ready, at the moment I think something is working but no way near to the stability of the tcl ones.
  2. Dave Welton
    about 21 hours later:
    Starkits are something I definitely should have included in the article - I'll try and mention that some in part 2. For those who don't know what they are, they are a single file executable that contains both Tcl, Tk, a database system (metakit) and, of course, your script. The whole thing comes in at under 2 megs, so it's a great way to deploy software you've written.
  3. Neil Madden
    1 day later:
    Hi David! Interesting article, which adds some more to my (limited) knowledge of Ruby. My biggest nitpick when I looked at the language was the limitation placed on blocks: it appears that a command can only accept a single block, which must come at the end of the argument list. That would seem to make creating things like if/then/else-style commands (e.g. try/catch/finally) more difficult than needed. I'm not sure why this limitation exists (I suspect it was dictated by the syntax, which would be disappointing, but I may be wrong on that).
  4. gabriele
    2 days later:
    neil: single-proc-arguments are special cased to get the advantage of a more algol-like syntax, and to have the advanatage of using a single expression, "yield" inside the method accepting the block. There is a presentation from matz named "yield to the block" or something like that I recall talks about this tradeoff (talking about lisp macros and smalltalk blocks and ruby blocks) that you may find interesting.
  5. Andys
    2 days later:
    There's another way to create a hash you might prefer: > Hash[*%w{ foo bar bee bop }] => {"foo"=>"bar", "bee"=>"bop"} Also, you can technically pass more than one reference to a piece of code in the argument list, but yeah, you can only yield to one block. - Andrew
  6. MikeD
    7 days later:
    Unlike you i have no scripting language or java experience, and agree with your comment on the enthusiasm and attitude of the Ruby community. I was recently forced into this realm with some Perl scripts due to my lack of unsuccessful attempts with Ruby makefile and DB2 UDB DLI/CLI. I am determined to go back and try again though. Just as an aside - why no Ruby links on your free software site? Ta for the non-technical perspectives!