« The Manchurian Candidate | Main | Tapeheads »

November 17, 2004

Ruby vs. Python

I promised Raj a rant about Ruby and Python.

In Python’s defense, it is a beautiful language. I recently had to read the code for SpamBayes, which was easy to read and understand. There were plenty of strange and new idioms which I hadn’t seen in Python before, but could immediately see the applicability of.

Python was designed for clarity and simplicity. The motto is “there’s only one way to do it” and I think that’s a very reasonable motto for a language to have. Programming languages are not like natural languages: they need to be restricted so that we can read them and get the job done. You need the features you need, and that’s it: a stripped down for loop which really only works with generators and containers, a trivial while loop, no do-while wackiness, nothing like that.

One of my favorite features of Python was introduced around 2.1 (IIRC): list comprehensions. In Python, you can say something like this:

foo = [f(x) for x in someList if x % 2 == 0]

What this does is basically apply a function f() against every even element of someList, and put all those results in the variable foo. This is a functional feature, inherited from Haskell, but which could be expressed in Python in the Bad Old Days using this semi-Lispism:

foo = map(f, filter(lambda x: x % 2 == 0, someList))

Now, I was the kind of fuckhead who would love to write huge nasty things using Python’s functional builtins, like the above example. This is one reason why I like Lisp now and also one of my two issues of disagreement between Guido and the whole Python situation at the moment. Guido says lambda isn’t any better than a named function. He’s right, but completely missing the point: anonymous functions are wonderful, there are lots of places where you can and should use them, and to discourage their use is just downright silly, especially when you already have them. As an aside, the other issue I dispute is the presense of “object” without enforcing that it be the parent of every class, directly or indirectly, and I also think that the presense of “object” in a multiple-inheritance OO language not based on message passing is dubious. But that is another rant.

Anyway, I was initially attracted to Ruby because it is gaining support and momentum, and it seems to draw equally from Perl and Python camps. I only know one person who is trying to learn it as a first programming language, so it’s also kind of unique in that it is mainly used by programmers who already know another language—Ruby is intended for programmers, not for instruction or students.

There are basically two paradigms in languages which I admire, and the rest basically suck. Those two are the Lisp model, and the Smalltalk model. We seem to be doomed to have something other than the Lisp model, because it’s just too simple and elegant and not complex enough and works always, so I usually wind up picking between the Smalltalk model which is pretty nice and some other hodge-podge model that isn’t even interested in correctness or completeness. REALbasic, for example, is based on the idea that programming should be easy, and it therefore prevents you from doing complex things in short statements.

Anyway, one of the things I like about the Smalltalk model is the “everything is a message” concept. The only language where that concept really and truly meets a portion of the Lisp model is Ruby, and the result is this: everything is a message, and all messages are expressions with values. Ruby’s block concept is very closure-intensive, so Ruby code tends to be centered around this methodology of, call the method to get at the location where your code needs to execute, and pass a block which will be executed there. So a lot of functions do some setup, take a block to use their value, and then do some teardown. It seems to reduce the need for exceptions quite a bit.

Ruby’s philosophy is very attractive to hackers. It draws more from Lisp than Python does in terms of power, and it draws from Perl/Sed/Awk the string manipulation angle, winning Perl hackers. The language is sound, so I advocate it at least partly to get people away from Perl, because you can do lots of Perl-like things, without the unstable ridiculous mess which is Perl. It’s also very easy in Ruby to collect all the values of an iterator and do whatever you want. I have a feeling I would have liked APL, because of how fond I am of list comprehensions, but in Ruby things can be much more fun. You never have to have more than one line of code; you can smash things together, tear them apart, work with sequences and ranges, and all from an OO paradigm that is open to extension. Ruby’s OO is very much there to facilitate life for you rather than constrain you; the whole mixin idea lets you get 95% of the benefit of multiple inheritance without actually having to implement the shitty graph resolution algorithms it would take to do it right.

Anyway, I mainly program in Ruby because it’s fun, and because this guy thinks it’s good, and he’s hilarious. :)

Posted by FusionGyro at November 17, 2004 11:46 PM

Trackback Pings

TrackBack URL for this entry:
http://www.clanspum.net/~fusion/blog/admin/mt-tb.cgi/55

Comments

Post a comment




Remember Me?

(you may use HTML tags for style)

Want HTML? Use Textile instead.