"Real" Differences Between Python & Ruby

I have a question about the difference(s) between Python and Ruby. I
have been working with both languages for about one year each now, and I
keep finding differences that turn out to be just syntactical. I will
elaborate, but this is the gist of my question:

What can Python do that Ruby can’t? What can Ruby do that Python can’t?
What does Ruby gain from its syntactic quirks, other than easier DSL
implementation?

I recognize that this is potentially a very “religious” question, so I’d
like to specifically note that I’m not talking about whether one
language is “better” or faster or easier to use. I’m just trying to
grok the real differences between Ruby and Python, and the reasons
behind the design decisions that created them as they are today.

For my comments below, please refer to the attached rar.

One example: A simple Python closure technique can be seen in clos.py.
This leverages Python’s simple first-class function support. However,
with very little effort, we can replicate the technique in clos.rb with
a lambda and the call() method.

Conversely, we can look at a good usage of Ruby’s block/yield
functionality in iter.rb. Again, with only a little bit of
head-scratching, we can translate this rather directly to Python using
UserList and, again, Python’s first-class function capabilities.

Even in terms of real closures, like the example in clos2.rb and
clos2.py, which I shamelessly stole from Google, Ruby and Python fail to
really outpace each other.

So, how do blocks in Ruby REALLY differ from lambdas in Python? Is
there anything you can do in one language that some fancy footwork can’t
achieve in the other, or is that the point of their differences? I know
all of the knee-jerk reactions: Multiple inheritance, syntactical
indentation, keyword arguments, regex literals… those are all either
matters of taste or easily simulated. What are the “real” differences,
if any? Was Matz’s intention in creating Ruby to approach existing
functionality with a new syntax, or are there things I’m not seeing?

Thanks so much in advance for all of your thoughts and comments. I’m
looking forward to seeing what everyone says, and solving this mystery!

On Wed, May 7, 2008 at 5:23 PM, Max C. [email protected] wrote:

I have a question about the difference(s) between Python and Ruby. I
have been working with both languages for about one year each now, and I
keep finding differences that turn out to be just syntactical. I will
elaborate, but this is the gist of my question:

What can Python do that Ruby can’t? What can Ruby do that Python can’t?
What does Ruby gain from its syntactic quirks, other than easier DSL
implementation?

One often-overlooked point is the design of the standard library. For
example, one of ruby’s major design decisions is the syntactically
convenient and addition of one free closure to every method, with a
lightweight, performant way to invoke it. That led to things like a
collection interface built around the concept of internal iterators,
the pervasive use of the open resource/ yield to caller/ close
resource pattern, and an avoidance of higher-order-functions and
patterns that would have required two lambdas passed in. Python both
makes inline anonymous closures highly inconvenient, and provides
cheap generators (something hard to do in ruby without a large
performance hit), leading to the more pervasive use of external
iterators. Also, rubyists like method chaining, and pythonists don’t,
which is why several methods in the python stdlib return None if they
are being called for their side effects, where a ruby method would
tend to return self.

martin

On 8 Maj, 04:09, Phlip [email protected] wrote:

Max C. wrote:

What can Python do that Ruby can’t? What can Ruby do that Python can’t?
What does Ruby gain from its syntactic quirks, other than easier DSL
implementation?

Python’s DSL support is pitiful. What you call a “quirk” is instead
the ability to make coding all_about those silly fringe quirky DSLs.


self.Phlip

dsl as in?

On Wed, May 7, 2008 at 8:23 PM, Max C. [email protected] wrote:

if any? Was Matz’s intention in creating Ruby to approach existing
functionality with a new syntax, or are there things I’m not seeing?

First of all, you seem to be coming at it from the assumption that
Ruby is a response to Python, or vice-versa. Both Ruby and Python
are far more influenced by their shared ancestors - Lisp, Smalltalk,
Perl, Modula, C, to name just a few - than they are by each other.
BOTH languages are “nothing new” in the sense that Lisp, Smalltalk,
Perl et al already had full fledged closure semantics when Ruby and
Python arrived on the scene. So yes, in that sense it’s just a matter
of syntax.

If you are interested in a closure-related feature that DOES
differentiate the two languages, look at continuations
(Kernel#callcc). Python, with the possible exception of the
Guido-disowned Stackless variant, does not support continuations. Of
course, with JRuby not supporting continuations and MRI 1.9 apparently
moving to Fibers, this may cease to be a point of differentiation in
the future. A prospect that I personally find disappointing.


Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

globalrev wrote:

|> Python’s DSL support is pitiful. What you call a “quirk” is instead
|> the ability to make coding all_about those silly fringe quirky DSLs.
|>
|> –
|> self.Phlip
|
| dsl as in?

Domain Specific Language.
Rake, Rails, RSpec, Adhearsion…


Phillip G.
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

~ - You know you’ve been hacking too long when…
…your friends who aren’t hackers wonder what happened to you.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgjir0ACgkQbtAgaoJTgL/V5QCgjYPKRNq17Ko/wHMVLahyLBp8
7QAAoJPB1pwy9dZKEox0hg0U1FLtZW72
=ea7W
-----END PGP SIGNATURE-----

I was about to comment on something but when i read this:

What does Ruby gain from its syntactic quirks
I could not really continue.
It reminds me of the terminology “monkeypatching”.
I dont really want to comment towards derogative terminology. (To me, a
quirk implies something derogative. Same as monkey-patching implies to
me as a “not good patch” that was applied under speed pressure, very
quickly and without much thought etc but using a derogative term for it
…).

I recognize that this is potentially a very “religious” question

I dont really think it is per se. But one maybe has to be careful
which words he uses. Unless that guy in question does not care
anyway maybe (mister “rails is a ghetto”) :slight_smile:

However, the python vs ruby comparison is, IMHO, really not such a
huge difference, because both share many goals. It is much more a
beneficial competition between the two.
With perl biting the dust (I could not resist … ;> )

One example - is that in speed comparisons, python outperforms ruby,
but I never understood why anyone who uses such “slow” languages
would care about speed anyway.

DSL is also a “difficult” term, because I have seen about 6 different
definitions of a DSL. It would be much better if people could all
agree about a DSL. And most importantly, if a DSL is a real language
WITHIN that language, or whether it is not.

However, the python vs ruby comparison is, IMHO, really not such a
huge difference, because both share many goals. It is much more a
beneficial competition between the two.
Really? Python just stands all the time in my way, ok it is the Ruby
way I am used to I have to admit. But I know enough Python to know
which one is easier on my fingers and my eyes.
Do not forget that Ruby’s design gool was to please Matz, we should
check with Guido if this was his design goal too ;).

With perl biting the dust (I could not resist … ;> )
Those been told dead live longest, and this might as well not be the
exception confirming the rule.

Robert

Hi –

On Sat, 10 May 2008, Marc H. wrote:

I was about to comment on something but when i read this:

What does Ruby gain from its syntactic quirks
I could not really continue.
It reminds me of the terminology “monkeypatching”.
I dont really want to comment towards derogative terminology. (To me, a
quirk implies something derogative. Same as monkey-patching implies to
me as a “not good patch” that was applied under speed pressure, very
quickly and without much thought etc but using a derogative term for it
…).

Also, a quirk can only be measured in relation to something non-quirky
– in this case, I guess, the syntax of other languages. (I don’t mean
to lay this at the feet of the OP of this thread; it’s a pretty
constant theme.) The sense that Ruby is uniquely accountable for the
ways in which it differs from other languages is very persistent. I’m
not sure why, especially now that it’s got such a large usership. Or
maybe that has something to do with it; I don’t know. It’s all very
meta-meta :slight_smile:

I recognize that this is potentially a very “religious” question

I dont really think it is per se. But one maybe has to be careful
which words he uses. Unless that guy in question does not care
anyway maybe (mister “rails is a ghetto”) :slight_smile:

However, the python vs ruby comparison is, IMHO, really not such a
huge difference, because both share many goals. It is much more a
beneficial competition between the two.

I remember hearing an intro presentation about Python where you could
have crossed out Python and put in Ruby and it would have been
exactly what people say all the time about Ruby: concise, elegant,
OO, doesn’t get in your way, etc. etc. The two languages definite
share many goals, and appear to have succeeded at them. (I’m not
interested in Python myself, but I do take Python programmers at their
word about what they love about it.)

With perl biting the dust (I could not resist … ;> )

One example - is that in speed comparisons, python outperforms ruby,
but I never understood why anyone who uses such “slow” languages
would care about speed anyway.

DSL is also a “difficult” term, because I have seen about 6 different
definitions of a DSL. It would be much better if people could all
agree about a DSL. And most importantly, if a DSL is a real language
WITHIN that language, or whether it is not.

It’s all about the ‘L’ :slight_smile:

http://dablog.rubypal.com/2007/4/17/the-l-in-dsl-langue-ou-langage

David

On Fri, May 9, 2008 at 1:13 PM, Max C. [email protected] wrote:

For example: No matter which
way you slice it, “arr.each { |item| item.foo }” and its underlying
implementation is unique to Ruby

It is?


Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

On Fri, May 9, 2008 at 1:29 PM, Avdi G. [email protected] wrote:

On Fri, May 9, 2008 at 1:13 PM, Max C. [email protected] wrote:

For example: No matter which
way you slice it, “arr.each { |item| item.foo }” and its underlying
implementation is unique to Ruby

It is?

Is there another language out there that lets you pass a “literal”
block of code as a virtual argument so the called method can push
arguments into the code block specified by | |s?

On Fri, May 9, 2008 at 8:01 PM, Max C. [email protected] wrote:

arguments into the code block specified by | |s?
Of course, with minor syntactic change. It’s called Smalltalk IIRC :wink:

Robert
http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On 5/9/08, Max C. [email protected] wrote:

arguments into the code block specified by | |s?

well except for the ||, what about c? Assuming an ‘Object’ struct has
been defined:

Object set[N];
//
int idSort(void* l, void* r) { /* Here’s my literal block of code
/
return ((Object
)l)->id - ((Object*)r)->id;
}
qsort(set, N, sizeof(Object), &idSort); /* Which I pass as argument
/
/
so the called method can push items into it
*/

What’s unique to Ruby (at least in your example) is not that I can
do it, just that I can do it in roughly a quarter of the equivalent c
code:
set = []
#fill set
set.sort_by{|o|o.id}

-Adam

On Fri, May 9, 2008 at 12:23 PM, Marc H. [email protected]
wrote:

I was about to comment on something but when i read this:

What does Ruby gain from its syntactic quirks
I could not really continue.
It reminds me of the terminology “monkeypatching”.
I dont really want to comment towards derogative terminology. (To me, a
quirk implies something derogative…

My usage of the term “quirk” was never intended to be derogatory. To
me, a “quirk” is simply an idiosyncrasy: something unique to a
particular group or idiomatic context. For example: No matter which
way you slice it, “arr.each { |item| item.foo }” and its underlying
implementation is unique to Ruby, and I’m really interested to see
why, specifically, Matz decided to do it that way, for that and other
decisions. Maybe a different spin on my question could be, “What
problems did Ruby solve, as a new language?”

  • M

On Sat, 2008-05-10 at 02:13 +0900, Max C. wrote:

Maybe a different spin on my question could be, “What
problems did Ruby solve, as a new language?”

I’m not sure that this is a meaningful question. What problems did any
language past patch cabling circuit boards solve? If you set the bar
low enough (or high enough) all current computer languages are imperfect
reflections of a Turing machine anyway. (Yes, even the functional ones
based on Church instead of Turing. They’re just REALLY obfuscated.)

As a former intensive Python evangelist (to the dread of my coworkers at
the time) and a now very happy Ruby user (despite Ruby’s many quirks –
and yes, I’m using the term here in its negative connotation) what I see
Ruby bringing to the table that made me switch is:

 1. A more flexible syntax which, while harder to learn completely,
    makes things easier to read when I have learned it.  As a
    trivial example there's no need for if...elsif...else...end,
    unless...else...end, ...unless..., ...if..., ...?...:...,
    case...when...else...end and all other such conditionals.  They
    can all be handled with if ... else ... end and nothing more.
    Yet the expressiveness of the language increases when I can pick
    and choose the construct that most accurately and succinctly
    expresses my intent.
 2. Just enough support for functional-style programming that I
    don't feel like I'm fighting the language each step of the way
    when I'm trying to accomplish things I'm used to doing now.  (If
    Ruby could add zero-stack tail recursion to its bag of tricks
    I'd be really happy!)  Python has some support for the
    functional style, but Guido is noted as not thinking that it's
    important to support and, I think, secretly puts barriers to
    proper functional programming in place because he doesn't like
    it.
 3. A far friendlier community.  This is not a technical reason to
    switch, but given the complexity of modern programming languages
    and the even greater complexity of the bewildering variety of
    libraries available a decent community is vital for a language.
    I would far rather use a "substandard" language with a great
    community than a great language with a snotty, unhelpful
    community.  I grew disgusted -- utterly disgusted -- with the
    Python community about eight years ago and have never bothered
    to poke my nose into the mailing lists, etc. since except for a
    few instances where I held my nose, asked my question, filtered
    through the hostile noise and found the answer.  If I got an
    answer at all.  The Ruby community is far more prone to good
    answers without the smart-ass syndrome -- although this is
    lamentably on the rise -- and far more welcoming to newcomers --
    although this is lamentably on a decline.  (Don't even get me
    started on the Common Lisp community of c. a decade ago.  Just
    Google for "Erik Naggum" for a representative example.)
 4. No syntactic whitespace.  While I initially liked and defended
    the indentation scheme of Python, it was because I only ever
    wrote my own scripts for my own purposes.  As soon as I had to
    work with another person using Python the weakness became
    evident.

Michael T. Richter wrote:

I’m not sure that this is a meaningful question. What problems did
any language past patch cabling circuit boards solve? If you set the
bar low enough (or high enough) all current computer languages are
imperfect reflections of a Turing machine anyway. (Yes, even the
functional ones based on Church instead of Turing. They’re just REALLY
obfuscated.)

Actually, I think it’s Turing and Von Neumann that were obfuscated –
Church and McCarthy got it right. :wink:

But seriously, I don’t recall having read any of Turing’s practical work
on design of real computers, but I have read Von Neumann’s, and there
is a certain elegance in Von Neumann’s design that I don’t think has
ever been surpassed, and it’s certainly much more elegant than a Turing
machine.

On Sat, 2008-05-10 at 14:52 +0900, M. Edward (Ed) Borasky wrote:

Michael T. Richter wrote:

I’m not sure that this is a meaningful question. What problems did
any language past patch cabling circuit boards solve? If you set the
bar low enough (or high enough) all current computer languages are
imperfect reflections of a Turing machine anyway. (Yes, even the
functional ones based on Church instead of Turing. They’re just REALLY
obfuscated.)

Actually, I think it’s Turing and Von Neumann that were obfuscated –
Church and McCarthy got it right. :wink:

Mathematically I agree with you, but in terms of hardware underlying all
this stuff it’s basically a real-world Turing machine. (Which is what
the von Neumann architecture is: Turing’s machine turned into something
that could actually be implemented. Things like “infinite tapes” and
“infinite decision tables” turned out, surprisingly, to be implausible
at point of implementation. :D)

Church’s model of calculation is far more appealing to me and the
languages based on it – Lisp (arguably: there’s some evidence that
McCarthy stumbled over this rather than deliberately trying to model
Church), Haskell, etc. – are increasingly the way I like to work. But
it’s all smoke and mirrors. Underneath it all is a von Neumann machine
masquerading as a Church lambda expression engine.

On 10 May 2008, at 07:31, Michael T. Richter wrote:

Church’s model of calculation is far more appealing to me and the
languages based on it – Lisp (arguably: there’s some evidence that
McCarthy stumbled over this rather than deliberately trying to model
Church), Haskell, etc. – are increasingly the way I like to work.
But it’s all smoke and mirrors. Underneath it all is a von Neumann
machine masquerading as a Church lambda expression engine.

Which of course drives home the point that all languages are about
useful abstraction, allowing those who use them to discuss problem
spaces without drowning in detail. In my experience Ruby is very good
at this even though it lacks some of the abstraction mechanisms I like
in other languages (such as Icon’s goal direction), but another
developer’s view may differ completely.

Why? Because language is not just a means of communicating between two
or more abstract and indistinguishable entities but a means of
transferring information between separate knowledge spaces in a manner
that will allow them to move towards a common representation of a
given problem domain. Its efficacy is therefore dependent on both the
structure of the language itself and the peculiar topography of all
the knowledge spaces.

In more concrete terms, there are programmers for whom Python is a
much closer fit to their stored knowledge base than Ruby, and vice
versa. It is therefore easier for them to investigate a given problem
domain using the one language than the other except in cases where the
problem domain itself is significantly more compatible with the other
language.

The same logic explains why some people love Lisp above all other
languages, and others would happily consign it to the bin of
‘academic’ languages :wink:

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

raise ArgumentError unless @reality.responds_to? :reason

Michael T. Richter wrote:

Mathematically I agree with you, but in terms of hardware underlying all
this stuff it’s basically a real-world Turing machine. (Which is what
the von Neumann architecture is: Turing’s machine turned into something
that could actually be implemented. Things like “infinite tapes” and
“infinite decision tables” turned out, surprisingly, to be implausible
at point of implementation. :D)

Again, I have to plead ignorance on Turing’s contributions to practical
computing. But the Turing machine was introduced in the context of logic
and foundations of mathematical logic, not as a conceptual foundation
for computing, either scientific or commercial. The same is true of
Church’s Lambda Calculus and Schonfinkel’s Combinatory Logic, as so
eloquently documented by (Haskell!) Curry and Fitch and numerous others.

The Von Neumann machine, on the other hand, was designed from the ground
up for the practical solution of equations – linear, nonlinear,
algebraic, differential, difference and integral. It was patterned on
successes of the past in this domain using electromechanical (relay) or
even mechanical technologies. Indeed, the original Burks/Von Neumann
design looks a lot like a programmable Marchant or Friden desk
calculator, except that the mechanical calculators were always decimal
and the Von Neumann machine was binary.

Church’s model of calculation is far more appealing to me and the
languages based on it – Lisp (arguably: there’s some evidence that
McCarthy stumbled over this rather than deliberately trying to model
Church), Haskell, etc. – are increasingly the way I like to work. But
it’s all smoke and mirrors. Underneath it all is a von Neumann machine
masquerading as a Church lambda expression engine.

McCarthy and others have written extensively on the origins of Lisp, and
I think most of the design decisions are well documented. But the key
concept McCarthy and the others introduced with Lisp is analogous to Von
Neumann’s. Von Neumann introduced the practical equivalence of programs
and data by storing them in the same address space. McCarthy introduced
the practical equivalence of programs and data by expressing programs as
S expressions just like the data. I don’t think either Turing’s or
Church’s “logics” do this.

Lisp 1 and 1.5 were indeed Von Neumann machines interpreting Church
lambda expressions. But later generations of Lisp machines arose that
carried out the interpretation at a lower level of hardware abstraction.

/There are two ways of constructing a software design. One way is to
make it so simple that there are obviously no deficiencies. And the
other way is to make it so complicated that there are no obvious
deficiencies. (Charles Hoare)/

Charles Anthony Richard Hoare, most often referred to as C. A. R. Hoare,
although I believe his friends call him “Tony”. :slight_smile:

On Sat, 2008-05-10 at 20:32 +0900, Eleanor McHugh wrote:

On 10 May 2008, at 07:31, Michael T. Richter wrote:

Church’s model of calculation is far more appealing to me and the
languages based on it – Lisp (arguably: there’s some evidence that
McCarthy stumbled over this rather than deliberately trying to model
Church), Haskell, etc. – are increasingly the way I like to work.
But it’s all smoke and mirrors. Underneath it all is a von Neumann
machine masquerading as a Church lambda expression engine.

Which of course drives home the point that all languages are about
useful abstraction, allowing those who use them to discuss problem
spaces without drowning in detail.

Oh, definitely. I’m not saying that said abstractions and layers are a
BAD thing at all! It’s why I’ve made sure I’m at least passingly
familiar with ~50 programming languages (not proficient: passingly
familiar). I want to keep my brain flexible with different ways of
thinking about the abstractions.

In my experience Ruby is very good
at this even though it lacks some of the abstraction mechanisms I like
in other languages (such as Icon’s goal direction), but another
developer’s view may differ completely.

I miss some of the stupid Haskell tricks I can do like trivial function
composition. I am also beginning to really enjoy Erlang’s approach to
parallelism and wishing I could do cool stuff like that in Ruby as
easily. But overall, yes, I agree with you. Ruby gives me lots of very
helpful tools for communicating abstractions succinctly and quickly.

The same logic explains why some people love Lisp above all other
languages, and others would happily consign it to the bin of
‘academic’ languages :wink:

Going back to point number … 4 was it? In my list? The Lisp
community is why I’m not a Lisper. I admire the language intensely and
would be a Lisp fanatic myself but for the fact that I despise its
community. I have never seen such a newbie-hostile, arrogant, unhelpful
set of people in my life. Whenever I hear a Lisper ask why Lisp is so
unpopular, I always have to suppress the urge to hold up a mirror.
(There are notable exceptions of course. Richard Gabriel, for example,
is one of the nicest people in any language community. Sadly the Erik
Naggums of the Lisp community outnumber the Richard Gabriels by about
two orders of magnitude.)

I am also beginning to really enjoy Erlang’s approach to parallelism
and wishing I could do cool stuff like that in Ruby as easily

Me, too. That was the impetus for dramatis
(http://dramatis.mischance.net; actor concurrency for ruby and python;
early but always looking for feedback.)

Apropos of the overall thread, I’m completing the port of dramatis to
python and the metaprogramming is pretty different. Python uses
metaclasses and doesn’t have the callbacks that ruby does. There’s
overlap in the feature set, but they don’t provide exactly the same
features.

More importantly, object dereference, e.g., “a.b”, is very different.
It’s difficult to do proxy objects in python, for example, rpc stubs,
because it requires accessing the object to know whether a.b is calling
a function (if b is a property) or simply binding a method pointer (if b
is a normal instance method).

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs