Ruby, Python compared
I wrote this as an answer to "querstrom" from informatik-forum.at, who asked about opinions on ruby and python.
I think the choice between Ruby and Python does not really make that much of a difference when in comes to productivity. Both languages are dynamic, made for object orientated programming and are enriched with elements from functional programming.
OO Design in Ruby is a little bit more consistent and more simple than in Python, but in my opinion, this does not give you that much of a productivity boost.
Both languages have a tons of libraries and a very active community around them.
If you look at Ruby and Python from an Java/C++/C# developers view, the differences are really not that significant at all. The advantages/disadvantages you find when using either of these languages will be more or less the same.
If you directly put Ruby and Python side by side, however, you will find some huge differences in the way their designers see OOP and programming in general.
1. Message passing vs. structural object design
Object oriented programming is often described as (reasonably) dividing an application into objects which have a state. If you want to change or if you want to know something about the state of an object, you pass a message to it.
In Smalltalk (and Ruby really is nothing else but a new version of smalltalk), this concept was taken very seriously.
lamp.lightswitch.press_button
This means something like "send the message 'lightswitch' to the object lamp. The answer to my request, which will be some object again, receives another message called 'press_button' ."
In Python, objects are seen more like in C++ or Java. Objects here are like containers that can hold other objects (of which some will be methods). I guess this has its roots in C's structs?
So,
lamp.lightswitch.press_button()
means in python: look into the object lamp for another object called "lightswitch". In lightswitch, find the object named "press_button" and call that.
So, the dot in Python syntax means "look into" and in Ruby it means "send message to"
In fact, the Ruby code I wrote earlier is just syntactic sugar for
lamp.send("lightswitch").send("press_button")
which is also valid ruby.
For the casual Programmer, this does not make that much of a difference at first. Python programmers can think about their programs in terms of message passing to objects without many problems. But if you start using the languages for real applications, you will find that much of the characteristics of the language come back to this idea of message passing vs. structural objects.
For example, it is only logical that you cannot have public instance variables in ruby, since the only way to communicate with objects is through sending messages to it. If it is at the right side of a dot, it has to be a message.
Because Python objects are really just containers, you can do something like this:
amethod = object.somemethod
amethod()
This is not possible in Ruby, since somemethod is not an method itself, but just a message to the object.
If you want the method object for some object in Ruby, you have to do what you always have to do: send a message to the object and ask for it:
amethod = object.method(:method)
amethod.call
There are tons of other consequences to these two views on objects. But I leave this now and describe another huge difference between Ruby and Python that is maybe even more relevant to programmers evaluating new languages.
2. The one obvious way vs. the principle of the least surprise
A basic principle of python (type "import this" in your python shell to see the basic principles) is that while there will always be million ways to solve a problem, there should better be one obviously best way to do it. This way, if one python programmer looks at some other python programmers code, everything will look familiar.
In practice this means, for example, that there are no switch statements or do...while loops or counting loops in python, since these are just other ways to do what you usually do with if conditions and foreach or while loops.
The ruby designers think a bit different. What really makes code hard to read is when the thought you want to describe is difficult to translate into program code. So if you want to do something if x is zero, Ruby allows you to write it down exactly this way:
do_something if x.zero?
This attitude has many influences on Ruby. For example, since many developers use pattern matching on strings every day, it makes sense to offer a special build in syntax for regular expressions right?.
Now many people see this and are instantly reminded of that lovely chaos called Perl. In fact, I think that nothing has hurt Ruby more than its perlish syntax, because it reminds people of chaos. In fact, ruby took some sytactic sugar from perl but that's it. Other than Perl, Ruby has a very clear and very slim grammar which is easy to understand and remember. The syntactic sugar is just that: Some few helpers that make code more comprehensible, but it just plain simple ruby under the hood. A Regex is an object as is String or nil: There is just an alternative way to create an instance.
3. Domain Specific languages
I do not want to write much about DSLs here, since Martin Fowler already wrote a terrific piece about DSLs. I just want to add that this really did make the choice for Ruby in my case, after some happy years with python as my main language of choice.
COMMENT: TITLE: A small typo AUTHOR: yyang EMAIL: DATE: 01/27/2007 06:48:14 AM Excellent article! A small typo: "import python" should be "import this".
COMMENT: REPLY: TITLE: oh your right. AUTHOR: benjamin.ferrari EMAIL: http://twoday.tuwien.ac.at/ferrari/ DATE: 01/27/2007 09:47:01 AM It's been a while since I did this. Thanks.
COMMENT: TITLE: Ends Abruptly? AUTHOR: RL EMAIL: DATE: 01/27/2007 05:20:53 PM A good start on the comparison, but why do you brush aside the point that "made the choice for Ruby"? It's one thing to not want to go back over DSLs in general (since, as you point out, others have covered that ground), but if this is an important point in the comparison of Ruby and Python, it should be elaborated.
In Fowler's article he presents a DSL and develops a parser & framework for that. Is this significantly easier in Ruby (I'm thinking of Python and Antlr)? Or am I missing your point entirely? I'm eager to hear details!
Right now I'm happy with Python but I'm quite open to switching, given sufficient understanding of the advantages.
COMMENT: TITLE: Point #2 AUTHOR: bcorfman EMAIL: DATE: 01/31/2007 08:18:46 PM No, what makes code hard to read is when the grammar increases without bound. Guido has always added new syntax to Python carefully, when it's been demonstrated that there is a significant gain for most use cases.
See http://laurentszyster.be/blog/jruby-vs-cpython/ for the clear visual difference between Ruby and Python.
Not only does a simpler (yet still powerful) grammar make Python easier to grok, it continues to pay dividends over time in terms of maintainability and performance.
1 comments:
For me it was the global keyword and the super syntax. I blogged about it here:
why-python-actually-why-not-python
I know that may seem petty, but it was the small things that led me to look closely at Ruby. Using "$" for globals makes it simple and obvious. And for the super syntax, read the post. I enjoyed reading this post, thanks.
Post a Comment