Why I Like Python more than Ruby

Note: I’ve been sitting on this one for a week. I don’t want to be misunderstood, Ruby is my second favorite language, and it has a lot to love. But I keep coming back to Python, and I think I know why. So, here goes:

roots 3Yesterday Last Week, I in response to a post by Dave Thomas, I wrote about optimizing for readability.

Dave Thomas post basically amounts to an homage to Ruby at the expense of Perl.

Dave likes Ruby because it is far more readable, and therefor more maintainable than Perl. So far I’m totally on the same page. Readability is critical to maintainability and extensibility, and that’s where most of the work on any successful software project is going to be done.

But, here’s where we part company at least a little bit.

I happen to prefer Python over Ruby because optimizing for readability is much more a part of the philosophy behind Python. Most of the lines from the Zen of Python have readability implications:

Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
roots 3Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.

Ruby makes better choices than Perl

But the language is still built around something they call “the principle of least surprise,” and the least surprised person here is the initial developer, not the code reader.

In practice means that there are several different names for the same array methods, and many array methods that are only slightly different from one another. If you are familiar with another language’s way to do it, the “least surprising” thing would be for that same method to just work on Ruby arrays right?

And this can make it easier to get started with Ruby. But there’s a downside, when reading Ruby code this means you may need to learn and remember all 78 different array methods. Some of them are obvious, .last will give the last element in the array. No worries there, and I like humane interfaces which give you easily understood and convenient functions, but this is just one example of how Ruby takes it too far, by forgetting that you will eventually have to figure out what eacy of those functions does in somebody else’s code.

Quick Ruby Quiz:

  • is there a difference between array.size and array.length ? (no)
  • How about array.map! and array.collect! ? (no)
  • What about array.delete_if and array.reject ? (yes, reject returns nul if no changes are made)
  • And for extra credit, why is there an array.collect (non-destructive) and an array.collect! (destructive) but not an non-destructive version of array.map! ?

I’ve been reading more Rails code recently, and while I like Ruby, and I admire Rails, I find myself constantly wishing I could hold more of this stuff in my head. I learned to write Ruby pretty quickly, but reading other people’s code has taken longer — just because there are lots of nooks and crannies in the built-in classes and modules that will take me a while to learn.

But Python makes better choices than Ruby:

Don’t get me wrong, I like Ruby. And it’s not particularly difficult to read. But the philosophy of the language designers led to design choices that emphasize writability over readability. And in that department I think the advantage has to go to Python. Python lists are easy to use, but more importantly I understood all of the list methods and how to use them in the matter of a few min. Perhaps Ruby’s arrays are more powerful that Python lists, but so far I’ve yet to find something that can be done in Ruby that can’t be done easily in Python.

I mean, think about it — even the things people complain about in Python, like the explicit self or significant whitespace, are designed to with readability in mind.

21 Responses to “Why I Like Python more than Ruby”

  1. 1Daniel Berger

    Yes, there is a non-destructive version of Array#map. I’m not sure what made you think otherwise.

    - Dan

  2. Daniel,

    I never tried a plain map() so I’m sorry about the misinformation.

    I just assumed it wouldn’t work because the API documentation the Programming Ruby section or arrays, and the online API documentation only mention the destructive map!()


  3. In order to get me to switch languages, I have to get some sort of big advantage to make up for the loss of expertise. As a long time Python programmer, I’ve never felt compelled to use Ruby. I’ve read through why’s guide and poked at Rails, but in the end I don’t come up with enough to merit a switch. I’m sure a number of Ruby programmers are in the same boat for Python, and I think that’s fine.

    The languages I’m currently investigating (Concurrent Haskell, Erlang, Clean) provide strong concurrency support, which I believe is the next frontier of programming due to the upcoming multi-core machines. In the Python community, Stackless provides concurrency primitives though I don’t think it can take advantage of multiple cores. Is there a concurrency effort in Ruby? All the Ruby news I hear gets drowned out by Rails.

  4. 4Daniel Berger

    The online docs show it, but you’re right, it’s not in Programming Ruby. I have a feeling it might have something to do with the way it was declared in array.c, which confused rdoc.

    I’ll submit a patch for that. :)

    - Dan

  5. Daniel,

    I could swear map did not show up in the online docs when I looked. But perhaps I’m nuts, or they fixed something since I looked.

    Anyway, it’s good to know that there is a non-destructive map, consistency is a good thing. ;)

  6. Karl,

    Unfortunately, I think the concurrency story in Ruby is even less compelling than Python. Ruby does not support native OS threads at all. Python’s Global Interpreter Lock limits the utility of threads, so for the multi-processor case, it’s not like Python’s OS thread support is a huge advantage here.

    I have some hope for PyPy, stackless, and alterantive implementations to help out here, but for now the best concurrency stories are in the more purely functional programming languages…

  7. 7Bob

    So Mark, now that you said it, do you feel liberated?

  8. 8Marcin

    Don’t forget that YARV will support native threads GILed as well as fine grained threads

  9. Bob,

    Yea — and the Ruby Hoards haven’t swarmed over to destroy me. So perhaps I hit the right tone after all. ;)


    YARV will make the world better someday, just like PyPy and Perl 6. ;)

  10. 10Marcin

    I agree ;), but YARV development seems to be quite active right now.

  11. 11zgoda

    So is Python 3000. This is one train to a better future. ;)

  12. 12André Næss

    I call this programming language ergonomics. When I write a lot of collection code in Java it feels painful. Like sitting on a lousy chair. And all those curly braces force me to keep pressing Alt-Gr and various other annoying combinations. It’s not just metaphorically painful, it’s physically straining! This is why I feel so great when I write Python compared to how I feel writing all the Java in my day-job.

    I also find that for operators outside of the standard arithmetic this also applies. For example, in the relational algebra most texts use various greek characters for the operations. I always find these texts hard to read because I have to remember what those greek letters mean in this particular context (these are after all some of the most heavily overloaded symbols out there). Reading Chris Date is a much nicer experience because he calls the operations join, restrict, summarize etc. I never have to translate from symbol to meaning. Operators seem to mostly degrade readability.

  13. 13Alec Munro

    I’m in roughly the same boat, as a long-time Python programmer who occassionally flirts with Ruby. I like it quite a bit, and generally, when I go to write something, it will do what I expect on the first or second try. However, I’ve never found it to read as well as Python. For myself, Python slices make so much sense I end up accidently using them in Java before Eclipse barks at me. Certainly, Ruby is fairly close in this department, when compared to Java or most other languages I have experience with, but there is just something simple about Python’s approach that makes me more comfortable with it. This may change over time, but that’s where I’m at right now.

  14. 14Bruce

    I was disappointed that Ruby didn’t follow python’s lead and use indentation instead of begin-end. Everyone always indents their code; the syntactic begin-end elements are left over from the days (C) when you did things to make it easier to write the compiler rather than make it easier to program.

    I was also disappointed with the requirement for “new” to make new objects, rather than Python’s non-redundant syntax. The new keyword is left over from C++ which required it to distinguish between stack and heap objects. It’s unfortunate that language creators (for both Ruby and Java) mindlessly echoed the “new” keyword without thinking “do we really need this?” That’s what makes it hard to leave Python, which says “if you don’t actually need it, we won’t make you type it.”

    The exception being the explicit “self”, which, regardless of how much it is justified, I think was not really well thought-out. The language should take care of it and not make you type it — Ruby +1 for that — and I hope to see a change in Python 3000.

    On that note, Python 3000 now has the opportunity to incorporate what works best in Ruby.

  15. 15Marcin Mielżyński

    the new is _not_ a keyword in Ruby, it is a plain class method and it _definitely_ comes from Smalltalk, not C++/Java (this is neither keyword nor special syntax). Python solves class contructors and instance initializers (__new__ and __init__, look at Python metaclasses) in much the same way (although it is more consistent in Ruby IMHO)
    Accidentally calling new in Ruby is far more explicit than Python’s parens :D

  16. Yes, indeed-y. I have always suspected that one of Python’s primary advantages over Ruby is easy source code readability (which is no small deal).

    This blog post confirms it.

  17. I like Ruby a lot. I think its a better designed language than python. There is one method that I don’t like in it. Its part of its default objject. to_s.. For none rubyist at first you wouldn’t think its for getting the string value of an object. The method should have been to_string for better readability.

    But overall, I like how Ruby is a better OOP language than Python. I’ll stick with Ruby.. Python is more mature in terms of library, tutorial, community.. etcs.. but Ruby will have its time.. its community is getting bigger and bigger so are its Libraries etc…


  18. Oh I forgot, Python’s interpreter is faster.. But then again as I’ve said everything in Python is more mature(exept for the language) as its been around longer. Ruby 1.9 will come out sometime in December this year and it will be the fastest Ruby Interpreter ever.

    Ruby is a better language imho, As is matures it will attract more users.

  19. 19perlist

    BS, ruby is more readable than python self and indentation diarrhea

  20. pearlist

    I don’t think you understand what I’m saying. I’m not arguing beauty. The ruby people do seem more interested in aesthetics. I’m saying python is easier to read and understand.

    Perhaps self is not the most beautiful construct in the world, but it hardly obscures the meaning of the code.

    And I call bullshit on calling python indentation an anti-readability issue. Consistent indentation makes code easier to read, and that’s a fact of how the brain processes block-data.

  21. Thanks!,

Comments are currently closed.