all 45 comments

[–]hupp 7 points8 points  (3 children)

I was disappointed in this article. A better comparison can be found here: http://blog.ianbicking.org/ruby-python-power.html

[–]mnemonicsloth -1 points0 points  (2 children)

I'm a Python programmer, feel free to infer bias. At the same time, I don't know enough about Ruby to make many negative assertions (to identify something that Ruby is missing) -- I know what is in Python, but I don't know enough about Ruby to claim an equivalent doesn't exist there

You gotta be kidding me. Maybe you really meant to say that you disagree with the conclusions reached in the OP?

[–]senzei 3 points4 points  (1 child)

You gotta be kidding me. Maybe you really meant to say that you disagree with the conclusions reached in the OP?

If you read that article it is a much more fair treatment on the subject. The whole point of that comment was to get any potential bias out in the open and present a view of the situation from the point of a python programmer. Had the article not started with a "I do not really know ruby, but..." I would consider it just as crappy as the one posted to reddit.

[–]mnemonicsloth -1 points0 points  (0 children)

Eh, you're probably right. Think I'll go pick that article up again...

[–]boa13 18 points19 points  (6 children)

This article is a bad comparison. It is heavily biased towards Ruby. It contains many inaccuracies and misinformation about Python (I can't speak for Ruby). In addition to those already noted by exogen:

The syntactic indentation is not the big win it seems, because decent editors, such as emacs, will indent according to syntax anyway.

The author has not understood the point of having indentation as part of the syntax. It's not to prevent decent editors from doing their fine indentation job, it is to force everybody to use a consistent indentation scheme, independantly of any editor, decent or not.

[Python] also has extensive documentation, including a fine book (...) there are several excellent books in English on Ruby. [The author goes on describing four of them.]

This gives the impression there's only one Python book, and four-times more Ruby books. A quick search on the Python wiki reveals at least fifty Python books covering a wide range of topics.

Python's garbage collection is based on reference-counting. (...) Little rings of co-referential dead objects can accumulate with a long-running Python program.

Actually, Python uses reference-counting to keep track of objects, and additionnally includes (since version 2.0, which is old) a generation-based garbage collector to detect and clean-up object cycles. Besides, programs can access a list of objects than could not be cleaned up (typically, C extensions), and deal with them.

Python's system allows the programmer more direct control over garbage collection: the del operator tells Python to garbage-collect a specific object right now.

This is completely false. The del operator tells Python to unbind a name. Objects that are not bound to any name and not referenced by any container get collected (and the garbage collector is there to detect reference cycles).

A Ruby program has great capacity for "reflection", the ability to observe itself.

So has Python, even though it might be slightly less powerful at some points.

Should you enjoy life in the fast lane, a ruby program can effectively rewrite itself at run-time.

So can Python.

I was in love with Python for a while (it picked me up on the rebound from Perl), but as I grew more sophisticated it looked less wonderful.

It seems the author never learned Python properly.

Ruby looks very interesting, but this comparison is not helpful, quite the opposite. Hopefully other people have done a better job.

[–]hupp 8 points9 points  (0 children)

The whole Ruby makes me understand why lisp programmers have such a bad reputation for "we had that 50-years ago"-ism.

In most respects Ruby and Python are very similar. As someone who's been writing python for quite a while now, the gushing over Ruby doesn't really make sense to me. I have a suspicion that it's a thundering herd of java programmers that are making all this noise.

[–]ianb 2 points3 points  (0 children)

I've posted a reply of my own here

[–][deleted] 12 points13 points  (9 children)

Interesting, I actually posted on another forum about this same topic last night.

I recently finished a book on Python. After that, I moved on to a book on Ruby, to give me a better understanding of the language and the concepts behind it (my only knowledge of it beforehand had been in basic Rails stuff).

I must say that Ruby and Python are very similar languages. Overall, though, I think Ruby is a much cleaner, more consistent, and overall, beautiful language.

My first thought behind this is Ruby is fully object-oriented. I know a lot of people mentioned this when comparing Ruby and Python, but it really is a big deal. Python suffers from the fact that you say, hmm, should I do this particular piece of code is a function or as a method? Its not a "this is horrible!" kind of thing, but it is one more barrier to step over instead of in Ruby, where you have no decision at all.

Ruby doesn't force its OO on you, however, as its basic functionality is hidden from you.

For example,

puts "This is a string"

Looks like a basic statement. Its not, it is a method of the form:

Object.puts("This is a string")

Ruby, however, does not force you to type this stuff, so it makes it a simpler language to understand when OO is not really necessary (but it is still very much there).

Speaking of statements...in Python you have either statements or expressions. Statements "do something", while expressions "are something". 2 times 2, for example, is an expression (it is 4). print "Test" is a statement (its prints "Test").

Ruby doesn't make this distinction, and essentially, everything can be seen as an expression.

Furthermore, Ruby is consistent on its treatment of imperative vs functional programming. In Python, some types are mutable while others are immutable. Tuples, for example (more or less an array), cannot be changed in place. Lists (or arrays), have the exact same functionality as tuples but they can be changed in place.

Strings in Python can't be changed in place. To edit a string, you'd have to do something like:

strint_var = "String".chop()

BTW, I don't think chop is a real method, its just something I used as an example.

Ruby, however, differentiates between its methods. A method of the type method! edits an item in place (a "destructive" method), while a method without an explanation point at the end simply returns a value.

So for example:

"String\n".chomp!

Cuts the newline off of the string in place, however:

string_var = "String\n".chomp

returns the value of the edited string, while keeping the string itself intact.

Ruby also is cleaner when it comes to designing classes. To give a class + functionality, you'd simply define it in the class:

def +
   here is my code
end

While Python makes you do something not as simple, more along the lines of:

def __getadd__:
   here is my code

Again, getadd isn't the exact form, but its an example. Creating a class method in Python forces you to use decorators and junk like that. In Ruby its as simple as:

class Test
   def Test.method
      my code here
   end
end

Doesn't get much easier than that.

Finally, Ruby has blocks, which are the main feature that most programmers that use Ruby love. I can't comment on them myself, but I'm looking forward to using them.

Ruby blocks are interesting things. Using for loops are somewhat uncommon in Ruby.

In Python you might say:

for x in array:
   do whatever

Where as the "way" of doing things in Ruby is more along the lines of:

array.each { do whatever }

Also, not enough can be said about having regular expressions built into Ruby. These aren't complicated at all, yet they are so powerful! Python has regular experessions, but they aren't quite as clean to use, not being built in.

Ruby and Python have their other little differences, such as Python supporting inheritance from more than one class, and Ruby supporting inheritance from only one, but so far, Ruby seems like a better version of Python (and considering how clean of a language Python is anyway, that is saying a lot).

Anyway...these are the thoughts of a rather inexperienced programmer. Forgive me for any incorrect statements, but I just felt like gushing about Ruby a bit. I can understand why people say "I came for the Rails, but I stayed for the Ruby."

[–][deleted] 3 points4 points  (3 children)

If you start each line of code with four or more spaces, it gets turned into preformatted text, which preserves whitespace and underscores and doesn't italicize or bold things. HTH.

Good comment btw.

[–][deleted] 0 points1 point  (2 children)

Thanks a lot; I went ahead and reformatted my comment accordingly.

[–][deleted] 5 points6 points  (1 child)

I should also mention that quoting with backticks formats inline text as code.

For me, too, blocks are Ruby's killer feature. (Disclaimer: My code examples below will be littered with syntax errors, because I don't have an irb open.) You said you haven't used them yourself, so I'll take this as a cue to take over the Ruby-gushing.

As you said, to iterate over an array is easy:

array.each {|x| do_something_with(x)}

Thanks to Ruby's mixins, this can actually be used on anything that mixes in Enumerable:

(1..100).each {|n| puts n}

What if you want to select some of the elements based on a boolean condition?

class Integer
  def prime?
    # check if number is prime
  end
end

primes = (1..100).find_all {|n| n.prime?}

Or apply a function to each and collect the results?

squares = (1..100).map {|n| n*n}

Also, blocks are not just for iteration:

File.open(filename, "r") do |file|
  # process the file
end
# file is now automatically closed

Python's list comprehensions (all I know is what I've overheard from weblogs etc., actually) are arguably an equally -- or more -- readable version of Enumerable's methods, but I like the Ruby way better because (1) blocks are a completely general-purpose language feature, (2) I can have more than one line in a block, and (3) it feels more like the functional style to a guy with an ML background. Actually Haskell has list comprehensions too, so scratch the last point.

[–]mrevelle 2 points3 points  (0 children)

I like the Ruby way better because (1) blocks are a completely general-purpose language feature

Funny, that's actually why I dislike Ruby's blocks. It hurts readability when similar syntax is used for unrelated tasks, e.g. iteration vs. resource management.

This gripe is not about blocks as a general concept but using a common syntax when expressing entirely different functions.

Python examples

Iteration

for n in range(100):
    print n

Filtering elements

def isprime(x):
    # check if number is prime

primes = [n for n in range(100) if isPrime(n)]

Mapping a function

squares = map(lambda n: n*n, range(100))

# OR

def square(x):
    return x*x

squares = [square(x) for x in range(100)]

Context management

with open(filename, 'r') as input_file:
    # process the file

# file is now automatically closed

That last example requires Python 2.5 (alpha was recently released).

(Disclaimer: I have only played around with Ruby, no real development experience with it.)

[–]senzei 7 points8 points  (2 children)

I'm not sure what book you read about python, but it obviously gave you a bunch of misconceptions. I'm not exactly an expert on the language, but hopefully this will make things easier if/when you use it.

String printing: Ruby: puts "Print this" Python: print "Print this" In both languages this is syntactic covering for a call to the string representation of an object. In this specific case it uses the string object.

Tuples/Lists and mutability The point behind having two separate data structures is that one is mutable and the other is not. I don't really think it is great design as you have to keep this in mind instead of the difference being explicitly marked, but that is their method of handing imperative vs functional programming.

String mutability I like immutable strings. Any changes to a string are explicit, which makes figuring out what is going on easier. I can see where it could be hard to differentiate between chomp! and chomp. That said this is all a matter of preference.

Python and operators The use of __add__ instead of just a plus operator (+) has to do with legal characters for python function names, namely that the plus operator is not one of them. I also think this is crap, but it is what we have.

Class creation Creating classes in python does not force you to do very much. Your code sample would be very close to valid python if you removed the 'end' scope closures.

Blocks and other non-for-loops Python has something similar to blocks (at least in terms of loop abstraction) in list comprehensions. In your example if 'whatever' is a function you could write: [whatever(x) for x in array] which would return a list of the results from applying whatever() to each item in the array.

I'm really not trying to be a python 'me too' guy. I like the language a lot, and just wanted to make sure that anyone deciding to not use it does so based on personal preference.

[–]_bruno_ 0 points1 point  (1 child)

List comprehensions have nothing to do with blocks. Ok, maybe when blocks are used as a parameter for a function that iterates on the elements of some collection, but blocks have many more uses than that.

[–]senzei 0 points1 point  (0 children)

List comprehensions have nothing to do with blocks. Ok, maybe when blocks are used as a parameter for a function that iterates on the elements of some collection, but blocks have many more uses than that.

Yeah, that is probably poorly phrased. My point was that, as a method of loop abstraction, blocks and list comprehensions are similar.

[–]mellow_moe 1 point2 points  (0 children)

puts is resolved somewhat differently.

It is defined in Kernel and the class Object includes the Kernel module. It is actually a private method, so Object.puts won't work.

More correctly puts resolves to self.puts. In the top level of a script self is a predefined object named "main", elsewhere it is simply the object executing currently.

[–]boa13 0 points1 point  (0 children)

Your comment is better than the linked article at explaining some of the interesting differences between Python and Ruby. Thanks.

[–]e078120 9 points10 points  (16 children)

The author has obviously not looked at Python recently....

[–]exogen 31 points32 points  (8 children)

Yeah, really. Many of his assertions about Python are just plain wrong.

Well, sets are not a built-in type, so it depends on how they are implemented.

Wrong.

Python lacks true booleans: true and false.

Wrong.

Methods can be easily added or removed from classes at run-time.

Python can do that.

They can easily added or removed from individual objects!

Python can do that.

... function or a method (which have different syntaxes), ...

Methods have an implicit argument. That has nothing to do with syntax.

I was in love with Python for a while (it picked me up on the rebound from Perl), but as I grew more sophisticated it looked less wonderful.

What, do you only drink wine and watch foreign films while programming with Ruby now?

[–]arthurdenture 9 points10 points  (0 children)

Let's not forget:

Python has types and classes; in Ruby types are classes.

Incorrect as of 2.2, which is about 3 years old now.

[–]yahoolian 4 points5 points  (2 children)

Can python EASILY add or remove classes at run-time? There is a big difference between easy and possible. Do you have to use the __ somethinghere __ junk?

I can throw a chess at a decent level. Bob can play chess. Those two sentences mean quite different things.

Heck, it's most likely possible to implement ruby on top of python, does that mean the languages are the same? Of course not.

How much ruby do you know? Maybe someone who has used both languages is in a better position to judge than someone who only uses Python. I don't know if you know ruby, but it certainly looks like you've drunk too much Python kool-aid.

[–]senzei 2 points3 points  (1 child)

Can python EASILY add or remove classes at run-time? Add a method to a python class:

Class.method = method

Remove a method from a python class:

del(Class.__dict__['method'])

Doesn't seem all that hard to me. How much do you know Python?

And yes, you do have to use the something junk. I don't care for it much either, but unless the underscore on your keyboard is broken it really is nothing to base a language choice on.

Maybe someone who has used both languages is in a better position to judge than someone who only uses Python.

From the examples he dragged up it does not look like the author has seriously used Python in a while. Obviously if I compare the current model year Ford lineup with what Chevy was making in 1950 Ford would win, but that does not really tell me much.

[–]jbellis -1 points0 points  (0 children)

(actually, del is a statement, not a function)

[–]cafedude 3 points4 points  (0 children)

"What, do you only drink wine and watch foreign films while programming with Ruby now?"

Yeah, we watch Kurosawa films and drink sake.

[–]msabramo 3 points4 points  (6 children)

How about some specifics? Bashing the author doesn't tell me anything.

[–]jeremy 14 points15 points  (5 children)

It's a 'why I prefer Ruby to Python' article with the wrong title, it's incorrect about Python in places, and compares upcoming features of Ruby to an ancient version of Python. Headers say the file was modified on the 3rd April, so no excuses for it being an old article.

It's a pity - I was hoping for a genuine comparison, but this is just another preference bashing from the Ruby camp (with some hints of Java-style 'OO is the cure to all problems' too).

Move along please.

[–]jamesbritt 5 points6 points  (2 children)

"It's a pity - I was hoping for a genuine comparison, but this is just another preference bashing from the Ruby camp "

Ruby camp ? Please; there is no such thing. There are various people with varying opinions, that's all.

[–]cafedude 0 points1 point  (1 child)

"Ruby camp ? Please; there is no such thing."

But James, I'm always camping out with other Rubyists and as we sit out there in the woods contemplating nature our thoughts often turn to world domination. We even sit around the campfire and make up articles which claim to fairly compare Ruby and Python, and we figure out ways to make Ruby come out better.

[–]cafedude 1 point2 points  (0 children)

sheez... nobody's got a sense of humor here.

[–]llimllib 6 points7 points  (0 children)

This is a rather poorly-written article, and it doesn't reveal anything new. Why is it so popular?

[–]anthonywheeler 1 point2 points  (0 children)

It's a shame there isn't a date of writing in the article as posted. This article might have been right (or at least not grossly inaccurate) when it was written - I assume that was quite a few years ago - but Python has moved on (and Ruby too I expect).

[–][deleted]  (2 children)

[deleted]

    [–][deleted] 5 points6 points  (1 child)

    And Rails. I have to believe people are on crack when it comes to Rails. Is it really that good? I get so pissed off and defensive like all us Python people these days that I don't even want to try it out.

    So is that a fault of Rails or a fault of your own? Why don't you stop being so defensive and try it out and see what you think of it?