Ruby versus Python

Posted by – 26/09/2009

This is not another rant to praise one in spite of the other (an everybody knows I love Ruby, so it would not be impartial), but sometimes people seems to live in another world and do things for the wrong reasons.

I just read this blog post by Kanwei Li in which he gives 2 or 3 reasons he ditched Ruby in favor of Python. First of all, both are great languages and, although I favor Ruby, I use Python for some projects and they are not all that different. Of course, everyone is free to choose which language one favors, but Kanwei seems to be “ditching” Ruby out of not knowing much about it, or out of preferring one style over the other…

His first “reason” is that in Python white spaces matter. I used to think this is just a matter of style, but every now and then mandatory alignment hurts me (just try to put together a code generator and you’ll notice it). Although my code is always correctly aligned, I like that it’s done so because I want it that way, and not because some language demands it. Rants and more rants have been written about Python’s mandatory alignment (or other languages lack of it), and I am not going through all of it… Just I don’t think it’s a good reason to ditch Ruby…

After, he makes a big deal out of Ruby’s ternary if. As written by him, he prefers

#python
if len(a) > 0:
        v = a[0]
        a = a[1:]
else:
        v = None

over Ruby’s ternary if

#ruby
v = a.empty? ? a.shift : nil

Hey! Come on… Ruby’s ternary if is not mandatory… It was copied from C just as a syntax sugar. You can do without it, just as in Python:

#ruby
if ! a.empty?
    v = a.shift
else
    v = nil
end

Better yet! you can use if’s return as v value:

#ruby
v = if ! a.empty?
    a.shift
else
    nil
end

How beautiful is that!

Python lacked ternary if for a long time, and when it finally acquired one via PEP 308 its syntax was made different from every other language! Although I don’t think that is a problem, some people might think it would be better not reinventing the wheel.

Next, Kanwei goes over a famous “problem” of Ruby: the lack of a sum method for Array. I admit it’s strange, but that is completely coherent: Ruby’s Arrays are ordered collection of objects and not mathematical arrays. How do you sum objects that are not numbers? Many different people will have many different answers to that, so Ruby leaves this decision for the programmer and provides basic methods to deal with collections of anything (that can be used to apply sum to numbers, if wished). So, in Ruby you have to use Array#inject to perform a sum:

[1,2,3].inject(0) { |sum, value| sum + value }

Array#inject (actually Enumerable#inject) was borrowed from Smalltalk and allows you to loop through an array, building up an “accumulator value” as you go. When it’s done, the final value of this accumulator is returned. Very useful for combining array elements, whether by summing them, building up a pretty display string, whatever. In the example above, I am initializing the accumulator with 0.

If you use Array to mathematical operations and you want your arrays to work that way, you can always add a sum method to Array class:

class Array
    def sum
        self.inject(0) {|sum, value| sum + value}
    end
end

Maybe it would be better if you just use Arrays as containers (as it was intended to) and implement that sum inside your own class… I completely agree with Reg Braithwaite here.

Kanwei also mention Python is faster than Ruby. That is true, but was “more true” some time ago. First of all, Python is older and has had more time to improve its speed. Ruby, ITOH, just now acquired a good VM and improvements to it finally can run parallel to improvements in the language itself, so I am expecting this to be less true every release. Python is already not getting much faster between releases, unlike Ruby (the differences between 1.8.7 and 1.9.1 are really impressive!). IMHO this is not a good reason to choose one instead of the other: if you really need speed, go for C 🙂

Now this is something I find interesting Kanwei has mentioned: “Python is more production ready”. He argues that Google is using it, so it must be good. Well… I cannot argue against that: Google is really using Python. But IBM, Oracle, EA, Cisco, Siemens, etc are using Ruby… so that is just a matter of preferring one or another company. Both are production ready… I agree, though, that Ruby 1.9.1 has many differences from 1.8.7, and that that may be seen as some inconsistency, but Python also has changed a lot since its 2.0 version, for that matter. And the changes to Ruby brought many benefits… I think they worth it.

At last, Kanwei compares Python and Ruby docstrings. Here I also have to agree with him: Ruby docstrings sucks. Actually that’s why everybody uses rdoc instead (and that is much more powerful than Python’s docstrings). Again, I don’t think that is reason enough to ditch Ruby (actually, the existence of rdoc, rubygems & friends should bring people to Ruby instead), but that is a matter of personal taste.

Surely, Kanwei’s reasons were easy to argue against. There are areas were Python shines much more than Ruby (and vice-versa), but those Kanwei mentioned are not among them.

I think both languages are powerful enough, and both are way better than Perl or PHP, so either one you choose would be fine. Better if you don’t have to choose and use both ;). If you have to, ITOH, pay more attention on how you feel while coding in each one, and not to some cheap reasons such as above. If you are a programmer, what matters most is that you’ll spend a lot of time coding with any given language… let that be something pleasant then.

12 Comments on Ruby versus Python

  1. spectra says:

    @Marcelo,

    I though about that… It seemed like one, until I checked Kanwei Blog for traditional April Fools jokes and found none. I was kind of following his Ruby algorithms project at GitHub and, since it haven’t got important commits since that post (lots of activity before, though) I just assumed otherwise.

  2. spectra says:

    @Aigarius,

    I don’t think that is true. Ruby is based in a handful of assumptions and stick to that (being the main two “everything is an object” and “methods are messages to objects”). Code readability is preserved in ways that comparing it to Perl is really unfair. All the magic you’re referring to can be track down to those few assumptions. Actually, it’s Python that has “magic methods” such as __len__, __nonzero__, etc. Comparing to Python’s technique, Ruby’s is much more uniform.

    Any sufficiently advanced technology is indistinguishable from magic. – Arthur C. Clarke

  3. spectra says:

    @divide_by_zero,

    I am not sure you read the full article. Although I provided every point in Kanwei arguments with an equivalent in Ruby side of the question, this was not intended to be a rebuttal. I agree with you that those are lame arguments…

    As I said, use whichever language you want, but don’t choose based on stuff like that. Try both and use the one you feel better with. In the end of the day, why not getting some pleasure programming since a programmer would spend most of his time doing it anyway.

  4. Troll says:

    Troll..
    Ternary em Python é mais legal.

    a = [1,2]
    v = a[1:] if a else None
    v
    [2]
    a = []
    v = a[1:] if a else None
    v

  5. Marcelo Madureira says:

    Isn’t that a April 1st post?

  6. Jon says:

    I think the construct
    “v = if ! a.empty?”
    Is hideous. The previous example’s one longer line is key. That one line adds so much legibility.

  7. Jan Larres says:

    Actually, you can write the sum of an array with inject (aka reduce) even shorter by using symbols:

    sum = a.reduce(:+)

  8. Aigarius says:

    For me Ruby contains and encourages way too much magic syntax with is non-obvious to newcomers and to the same developers after a few months. Just like Perl, Ruby just looks like it will be a pain to modify in a year or two, when you’ve forgotten what each part of it does.

  9. SLi says:

    Knuth designed TeX, a language with what, 40? different if statements. That alone is proof that his license to design programming languages should be taken away rather than ask him to compare two programming languages 🙂

  10. You could also write “v = a.pop(0) if a else None” in python. But I would not use it, because its not that clear that it actually modifies a.

  11. I prefer a C vs. fortran, basic vs. logo or smalltalk vs. oberon debate over ruby vs. python any time of the day. What lame arguments, on both sides!… I’m sorry, but I got the impression all these complaints are miles away from real-world programming difficullties.

    And AFAICT there is people working both with python and ruby in all these companies listed, all of them happily indenting the code the way the languages require or not, and thinking way beyond syntax.

    I would just love to know: what would Knuth say about ruby vs. python?

Leave a Reply

Your email address will not be published. Required fields are marked *