Sunday, October 14, 2007

Ruby, Smalltalk and Lisp Revisited

In my last post I suggested that Ruby may have some advantages over Smalltalk, especially when it comes to borrowing some of the more powerful features of Lisp. First thing to say is titling the post "Ruby versus Smalltalk" wasn't the cleverest thing to do. The responses tended to contain more heat then light. I hold up may hands and take full responsibility for this. Given the amount of FUD that Smalltalk has suffered over the years, it is hardly surprising that the Smalltalk community are protective.

I've been recently looking closely at Rubinius, a Ruby implementation that uses a Smalltalk/Squeak-like VM. Rubinius borrows many of the architectural ideas of Smalltalk/Squeak and is Ruby implemented mostly in Ruby. Eventually even the VM will be implemented in a C-like variant of Ruby called Cuby, much like how the Squeak VM is implemented in Slang.

I'm pretty taken by Rubinius. The approach taken is to implement Ruby right, and in so doing they've gone back to Smalltalk. The other thing that is very impressive is that all the Ruby libraries in Rubinius are implemented using BDD. So there are Rspec specifications for all library methods. The full Ruby library is not complete yet, but using Rspec is an excellent way to finally specify the Ruby language and in so doing allow lots of people (like myself :^)) to get involved in the Rubinous project.

So back to Lisp. The Rubinius compiler generates a simple Lisp (s-expressions) as an intermediate form on the way to byte code. There are lost of good reasons to do this, many of which are dicussed here:

Another reason not mentioned is that Lisp can become a common intermediate form allowing several source languages to interoperate. So Ruby or Smalltalk could be compiled to Lisp then Lisp to byte code. Peter Frisk has already implemented a Smalltalk to Lisp parser in Vista Smalltalk so this is possible. It also fits in nicely with the language orientated programming ideas that Martin Folwer has been touting for quite some time now.

Rubinius is gaining a lot of momentum in the Ruby community. So why is Lispyness important? I think the answer is flexibility and allowing change. Something that Alan Kay said seems relevant here. The first Smalltalk implementastions where built with Lisp I believe, and whilst Smalltalk was still within the confines of Xerox Parc the language was being experiemented with and changed all the time. Alan Kay complains that once Smalltalk became public in 1983, the language became fixed. He had hoped that Smalltalk-80 would be redundnant by now, and that it would have ben replaced by something better.

The Ruby community seem up for evolution, whilst also being a very practical bunch. The Rubinius project is cooperating with the JRuby project to specify a common Ruby across all implementations, something that I believe was a problem within the Smalltalk comunity. By considering how best to bring Lisp to Ruby they are also showing an openess to change. Matz seems open to change too, Ruby 2.0 although not revolutionary, does show a willingness to deprecate old features and break backwards compatibility, in the same spirit as pre Smalltalk-80 Smalltalks.

I still think that Ruby is closer to Lisp then Smalltalk, but that doesn't stop Smalltalk inlining Lisp or adoptng more Lisp like features if it wants to. In a sense the two languages share a common root. The difference seems to be history and the two communities. The Ruby community seem to be more willing to experiement and evolve, whilst the Smalltalk community is still holding onto Smalltalk-80 as the common Smalltalk dialect. I guess the question is whether the Ruby community can evolve together and stay as one, avoiding the fragmentation that occurred with Smalltalk.

From what I've seen on the web, there is plenty of reason for optimism. If the Rubinius/JRuby people pull it off we may end up in a situation where we don't need to choose. We can mix Ruby, Smalltalk and Lisp as and when appropriate.