Strong advantages over Python

Hi lovely Ruby people,

I’m a Ruby programmer and I’m tutoring at the University of New South
Wales in Australia, a course which includes Python in its syllabus.
Needless to say, I’m in an excellent position to promote Ruby and I have
been doing so with the lecturer in charge and among students in my lab
classes.

The lecturer has agreed to let me give a lecture on Ruby (to
a couple of hundred university students who have just learnt Python).

I’m writing to ask for a few examples of things one can do in Ruby which
are much more difficult in Python. Aside from the many ways in which
Ruby is a little easier than Python (the net effect being substantial,
IMO), what are some ‘real’ differences that show up in practice?

Specifically, this is what my lecturer is asking me:

I still can’t find a good comparison with Python that is not
superficial. Sure, Ruby might be better designed, but how does
this affect you in practice? Can you give an example of something
that can be done in Ruby that would not be so easy in Python?

My answers currently include ‘meta’ programming (trapping undefined
method calls, defining new class/module methods/attributes dynamically,
etc.), refactoring control flow (Python has generators but they’re more
clumsy to use), invisible resource management (e.g. File#open { …
}), Array and Hash being extensible classes (Python has UserList and
UserDictionary, but they’re annoying and AFAIK do not work well with
the existing control structures which expect primitive lists and
dictionaries).

···


Greg McIntyre
greg@puyo.cjb.net
http://puyo.cjb.net

>> I still can't find a good comparison with Python that is not >> superficial. Sure, Ruby might be better designed, but how does >> this affect you in practice? Can you give an example of something >> that can be done in Ruby that would not be so easy in Python?

just my 2 cents:

  • Iterators
    you can totally abstract your logic from the inner knowledge
    of a class. I think this is so good that they imported it
    in 2.3 :slight_smile:

  • Complete OO
    ok, you may say: why do I need it?
    and I say…

  • (Coherent +Simple) Language
    in python you see someway obj.method and someway met(obj)
    and in the past you had differences beetween types
    and classes, you need to write an add method to have “+”
    , I see methods anywhere and so on.
    Actually I even dislike literals in ruby, I admit it.

  • POLS+Syntax sugar
    when prototyping with one of those language, you’ll love
    them, if you need to remember how to do one thing you may even
    write directly the code in ADA. You’re at the High Level ain’t
    you?

But, anyway, you know, every language will fall into
The Big Language Crash, when every language would be multiparadigmish,
OO, interpreted, VM’ed, dinamically typed, with lambda and
cotinuations and substantially based on Hashes, and you would have
translators from MyLang to Lingo++ that would simply change the #!
line in the script file :slight_smile:

···

il Thu, 20 Mar 2003 10:59:03 +1100, Greg McIntyre greg@puyo.cjb.net ha scritto::

“Greg McIntyre” greg@puyo.cjb.net wrote in message
news:20030320105903.0ea6f349.greg@puyo.cjb.net

I still can’t find a good comparison with Python that is not
superficial. Sure, Ruby might be better designed, but how does
this affect you in practice? Can you give an example of something
that can be done in Ruby that would not be so easy in Python?

IMHO the Object Orientation in Ruby is better than Python.

Also, writing cross platform multi-threaded applications in Ruby is much,
much
easier … and this is not my “opinion”. Take, for instance, the 20-odd
lines code
fragment from Chapter 11 , Threads & Processes, Page 113 of the Pickaxe book
which downloads a set of Web pages in parallel. Now try to write this in
Python.
See for yourself which is easier to understand and follow.

(I owe an year-long project to that code fragment … thanks to Matz,
Dave,Andy).

Let us know what you experience.

– shanko

In article 20030320105903.0ea6f349.greg@puyo.cjb.net,

···

Greg McIntyre greg@puyo.cjb.net wrote:

Hi lovely Ruby people,

I’m a Ruby programmer and I’m tutoring at the University of New South
Wales in Australia, a course which includes Python in its syllabus.
Needless to say, I’m in an excellent position to promote Ruby and I have
been doing so with the lecturer in charge and among students in my lab
classes.

The lecturer has agreed to let me give a lecture on Ruby (to
a couple of hundred university students who have just learnt Python).

I’m writing to ask for a few examples of things one can do in Ruby which
are much more difficult in Python. Aside from the many ways in which
Ruby is a little easier than Python (the net effect being substantial,
IMO), what are some ‘real’ differences that show up in practice?

Specifically, this is what my lecturer is asking me:

I still can’t find a good comparison with Python that is not
superficial. Sure, Ruby might be better designed, but how does
this affect you in practice? Can you give an example of something
that can be done in Ruby that would not be so easy in Python?

My answers currently include ‘meta’ programming (trapping undefined
method calls, defining new class/module methods/attributes dynamically,
etc.), refactoring control flow (Python has generators but they’re more
clumsy to use), invisible resource management (e.g. File#open { …
}), Array and Hash being extensible classes (Python has UserList and
UserDictionary, but they’re annoying and AFAIK do not work well with
the existing control structures which expect primitive lists and
dictionaries).

Ruby has continuations whereas I don’t think they exist in Python. I was
able to do some things with continuations (in RHDL) that would have been
rather difficult to do without them.

How about Ruby’s code blocks and the ease of turning them into procs
(lambdas)?

Phil

Greg McIntyre wrote:


My answers currently include ‘meta’ programming (trapping undefined
method calls, defining new class/module methods/attributes dynamically,
etc.), refactoring control flow (Python has generators but they’re more
clumsy to use), invisible resource management (e.g. File#open { …
}), Array and Hash being extensible classes (Python has UserList and
UserDictionary, but they’re annoying and AFAIK do not work well with
the existing control structures which expect primitive lists and
dictionaries).

Please verify these publically before you teach this stuff to these
students. I’m not going to get into an argument about whether Ruby is
better than Python, but I do know for a fact that Python can do some
things that you say it cannot. There may be nuances that are unique to
Ruby but the overall features are there.

For instance:

~/p4/usr/pprescod> cat foo.py

class Foo:
def getattr(self, attrname):
return lambda : attrname

f = Foo()
print f.a()
print f.b()
print f.c()

Foo.special = lambda(self) : “In dynamically assigned method”
f.special()

f.special2 = lambda : “In per-instance dynamically assigned method”

print f.special2()

for i in range(0, 10000):
file = open(“/tmp/test.txt”)

class MyDict(dict):
def foo(self):
return “foo”

class MyList(list):
def bar(self):
return “bar”

d = MyDict()
d[“a”] = 5
d[5] = “a”
print d.foo()

for i in d:
print i, d[i]

m = MyList([1,2,3,4])
m[0]= “a”
print m.bar()

for i in m:
print i

class MyInt(int):
def doSomething(self):
return “Did something”

x = MyInt(5)
print x.doSomething()
~/p4/usr/pprescod> python foo.py
a
b
c
In per-instance dynamically assigned method
foo
a 5
5 a
bar
a
2
3
4
Did something

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

···


Greg McIntyre
greg@puyo.cjb.net
http://puyo.cjb.net

ptkwt@shell1.aracnet.com (Phil Tomson) wrote:

Ruby has continuations whereas I don’t think they exist in Python.

Well… you can always pass a few lambdas, or a few function names, as
arguments in Python.

How about Ruby’s code blocks and the ease of turning them into procs
(lambdas)?

The various uses for blocks and examples of how they make life easier
would be one focus of the lecture. But I’m interested in specific
examples where the equivalent Python code is significantly more
difficult.

···


Greg McIntyre
greg@puyo.cjb.net
http://puyo.cjb.net

Thanks, that’s the kind of thing I want. I’ll look that up when I get
home.

···

“Shashank Date” sdate@everestkc.net wrote:

Also, writing cross platform multi-threaded applications in Ruby is
much, much
easier … and this is not my “opinion”. Take, for instance, the
20-odd lines code
fragment from Chapter 11 , Threads & Processes, Page 113 of the
Pickaxe book which downloads a set of Web pages in parallel. Now try
to write this in Python.


Greg McIntyre
greg@puyo.cjb.net
http://puyo.cjb.net

There are a lot more than this, but these are just a few things that spring
to mind:

o Super easy to extend with C modules
o The power of mixing in Enumerable
o Simplicity of mixins vs multiple inheritance
o A builtin class library small enough to memorize but powerful enough to
do basically anything you want
o Total syntactic consistency(everything is an object)
5.times {|num| …}
“foo”.reverse
o Stronger typing(everything has a specific type)
1.type => Fixnum
o Truly private data instead of name mangling
o No equivalent of a do … while statement
o self.myvar vs @myvar
o No closures in Python?

I’m not a Python expert, so forgive me if anything above is incorrect.

Hope this helps,
Travis Whitton

[Side question] Is there no access control?

···

On Fri, Mar 21, 2003 at 07:08:06AM +0900, Paul Prescod wrote:

Please verify these publically before you teach this stuff to these
students. I’m not going to get into an argument about whether Ruby is
better than Python, but I do know for a fact that Python can do some
things that you say it cannot. There may be nuances that are unique to
Ruby but the overall features are there.

For instance:

~/p4/usr/pprescod> cat foo.py

class Foo:
def getattr(self, attrname):
return lambda : attrname

f = Foo()
print f.a()
print f.b()
print f.c()

Foo.special = lambda(self) : “In dynamically assigned method”
f.special()


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

what’s the difference between chattr and chmod?
SomeLamer: man chattr > 1; man chmod > 2; diff -u 1 2 | less
– Seen on #linux on irc

Thanks Paul. Sometimes its easy for those of us who are very familiar
with Ruby to neglect features of a language we are less familiar with.

It sounds to me as if the original poster is looking for a “slam dunk”
for Ruby (compared to Python), and I’m not sure he’s going to find one.
Ruby and Python have far more in common than they have differences.
What differences there are more more differences in preferences than
real differences in language power.

The truth is that I was on the verge of making a real effort to learn
Python when I read a posting by Dave Thomas (perhaps on the XP mailing
list?) mentioning Ruby. If it weren’t for that fortuitous posting, I
might be a Python advocate today (shudder :-).

···

On Thu, 2003-03-20 at 17:08, Paul Prescod wrote:

Please verify these publically before you teach this stuff to these
students. […] I do know for a fact that Python can do some
things that you say it cannot.


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

Irregardless of the benefits of Ruby over Python I do not believe that
dissing one language to make another look good is any way to promote
that language. It is the sort of trick that politicians with weak
arguments are wont to use.

If you want to show how good Ruby is give them some programming
exercises in Java for a term and then switch over to Ruby. When they see
that they can write the program without all that ‘scaffolding’ they will
be impressed.

Or perhaps teach them OO in Ruby for it’s simplicity and then switch to
Java and watch their hair fall out.

I’m sorry this thread has grown OT.

Please verify these publically before you teach this stuff to these
students.

That’s what I was asking: for somebody to correct me if I was wrong.
Well I was, I’m very sorry. Thankyou so much for putting me straight. I
don’t want to sell Ruby to my students; I want to let them make their
own informed decisions.

I’m not going to get into an argument about whether Ruby is
better than Python…

That wasn’t my intent. I wanted to clarify some of the differences which
were not merely matters of opinion (hence ‘strong’ advantages).

…but I do know for a fact that Python can do some things that you
say it cannot.

This is due to my inexperience with Python. I’m sorry. I do not want to
misrepresent Python. The lecturer is a Python expert and he will surely
correct and further mistakes I make regarding Python’s details.

~/p4/usr/pprescod> cat foo.py

[snip!]

Thankyou again.

···

Paul Prescod paul@prescod.net wrote:


Greg McIntyre
greg@puyo.cjb.net
http://puyo.cjb.net

Interesting.

My only quibble is when you say that in Ruby, types and classes are the same
thing.

I don’t know any Python, so maybe you are trying to say that the role of
"types" in Python is taken care of by classes in Ruby… i.e. there is
another kind of thing in Python called a “type”, but Ruby unifies that
concept with the “class” concept. Maybe that’s what you mean… I don’t
know.

But (at least outside of the Python-comparison context) it’s incorrect to
say that classes and types are the same thing in Ruby. Ruby has what I
think they call “duck typing”: If it walks like a duck and talks like a
duck, it’s a duck. (Or something like that. :slight_smile:

For example, let’s say I consider something to be a duck if it has a quack
method, that is, if:
`obj.respond_to? :quack’

I can turn a string into a duck pretty easily:
str = ‘duck’ # not a duck yet
def str.quack
puts ‘coin, coin’ # a french duck, of course
end

now str is a duck

So I have implicity “defined” a duck type without ever making a Duck class.
In Java I would need a class or an interface or something, but in Ruby
that’s all behond the scenes.

Sorry if this seems off-topic, but that’s what “type” refers to usually (at
least I thought so).

Chris

Greg McIntyre wrote:

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

It’s very nice. I hope it ends up on the ruby-lang site or somewhere
comparable.

One minor problem. In recent versions of ruby,

“hello”.gsub(“[^aeiou]”) …

will not treat “[^aeiou]” as a regex but as a literal string, and there
will be a warning. So for compatibility this should be

“hello”.gsub(/[^aeiou]/) …

Also, something you might want to point out that would appeal even to
people who are still going to use Python for general purpose
programming: Ruby, like Perl, is great for one-liners. (This was pointed
out as an advantage over Python in http://ruby-talk.org/45398) I’m sure
folks on this list will come up with many examples, if you want them…

Greg McIntyre wrote:

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

On Philosophy:

···

==============

Is this really how a Ruby programmer would characterize POLS? To be
honest, the way you state it, I wouldn’t be interested in either
Python or Ruby. A language that tries to cater to everyone’s tastes is
doomed to failure. Sounds like the popular image of Ada!

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img4.html

I would say POLS is: “Ruby attempts to conform to programmer’s
intuitions.” But then any decent language, operating system or user
interface strives for POLS. I admit that some fail badly. :wink:

As far as “Only One Way To Do It.” I’m sure that the way you describe
Python is not how a Python programmer would! :wink: Let me try:

“Only one way to do it.”

"Also known in computer science literature as "orthogonality", Python 

attempts to reduce to a minimum the variant ways of “spelling” a common
construct. This improves the regularity of code, reduces the size of the
Python language and makes reading other people’s code easier."

But I don’t expect you to put in such a Python-positive spin!

If Python is “rigid” what does that say about Java, COBOL, Pascal, C and
other similar languages that are much more strict than Python?

Re: type and class. Consistency of method use is unrelated to the
issue of type and class. It has always been the case that Python types
could have methods. The array type has always had methods. If you want
to knock Python for being inconsistent about functions versus methods it
would be more straightforward just to do so.

====
On Private Variables

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img6.html

First, I don’t think your Python code will behave as you say it does. It
won’t throw an exception (though there are ways to code the class that
would make it do so).

Second, add a second underscore and see what happens.

Third, Python doesn’t the title is misleading. OOM is something that
happens completely separate from coding in a particular programming
language. It’s widely understood to be UML-style stuff. Really you’re
talking about enforced encapsulation (as opposed to voluntary
encapsulation).

Fourth, I think that in both Python and Ruby there are hacks that will
allow you to get at “private” variables. In Ruby, it is instance_eval,
right?

====
On Syntax

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img7.html

Ruby also has more ways of spelling things, e.g. if statements that
follow their tests and magical Perl $_-style variables.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/ruby/img8.html

====
On Blocks

You say that Python has generators which are equivalent to Ruby’s
blocks. I think that blocks and generators are mostly unrelated. IMO,
blocks are just unnamed closures with a nice syntax. I can’t think of
any situation where you can accomplish something with blocks that you
can’t with closures. (although block syntax is arguably simpler)

But generators do allow you to do something that is very difficult
without them. Consider this code:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66316

What makes this interesting is that the generator “g” is an object that
can be passed around from place to place through your program. A
function that takes a closure/block doesn’t have that ability. There is
probably a way to accomplish this in Ruby (doesn’t Ruby have full
continuations?) but I would say that’s a separate feature than just
blocks/closure/functions.

The nice thing about blocks (compared to straightforward higher order
functions) is that they have a nice syntax. But I think that they are
more limited in that you can pass many higher order functions to a
procedure but you can only pass one block (unless you wrap it in a
function!). I think.

e.g.

def upload(handle_data_func, output_func, print_error_func, block_limit)
for blocknum in 0, block_limit
try:
block = read_block_from_network()
output_func("block received " + blocknum)
handle_data_func(block)
except:
print_error_func(“something screwed up”)

upload(handle_data_func = lambda data: blocks.append(data),
output_func = lambda data: logger.write_msg(data),
print_error_func = lambda: logger.write_err(data),
block_limit = 5)

Paul Prescod

Greg McIntyre wrote:

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

Despite my comments and corrections, it is a pretty good set of slides.
If you want more for the Ruby side, you could add syntax-integrated
regular expressions and continuations (though those are a little esoteric).

I found this page on how you can emulate generators with continuations:

Also, Ruby has “microthreads” which are better in many circumstances
than OS threads (which are better in other circumstances). To get
microthreads in Python you need to use the Stackless fork. To be honest,
I think that OS threads tend to be more useful more often but opinions
could vary.

Paul Prescod

Hi –

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

Overall it looks good to me (though I say that as a Python
know-nothing – mainly focusing on the Ruby stuff). There’s one
example I think is misleading:

Private attribute x of class A in Ruby:

class A
def initialize; @x = 0; end
end
a = A.new; a.x = 1 # exception!

The problem here is that there is no method x, private or otherwise.
The example implies that having an instance variable causes a private
reader method to spring into being. In fact, there’s no special
relationship between instance variables and methods with the same
names. The attr_* methods are handy but they’re basically just typing
shortcuts.

(This might also have implications for the equivalence you draw between
“self.attribute” in Python and “@attribute” in Ruby, but I’m not sure
exactly what’s going on on the Python side there.)

David

···

On Mon, 24 Mar 2003, Greg McIntyre wrote:


David Alan Black
home: dblack@superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

These are comments only on the Ruby part (I know nothing about Python):

Slide 3, bullet point 1: Ruby is strongly typed (all objects have a
type) and dynamically typed (type is determined at run time).

Slide 4, POLS: Ruby syntax is familiar to those who have programmed in
C, Lisp, Perl (especially as to regular expressions) or SmallTalk, but
is accessible to those who have never programmed before. The initial
learning curve for Ruby is very easy for almost anyone first
encountering the language.

This is another outstanding addition to the resources introducing Ruby
to new users.

···

On Sunday, March 23, 2003, at 12:52 PM, Greg McIntyre wrote:

[snip]

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/

[snip]

From text12.html (the title says slide 13):

The Ruby Application Archive has hundreds of downloadable modules
for specific tasks including ports of nearly all common C/C++
libraries

Problems:

  • ports? more like wrappers (“port” implies it has been
    reimplemented in Ruby)
  • “nearly all” common C/C++ libraries? I doubt it, although
    I could be wrong

Gavin

···

On Monday, March 24, 2003, 4:52:52 AM, Greg wrote:

Thanks to all of you who answered and cleared up some of my perceptions
about Python. As a result I’ve put together some slides introducing Ruby
to Python programmers (hopefully without any misinformation!).

This is a 30 minute lecture on Ruby, aimed at 3rd year university
students who have just learnt Python. Feedback welcome.

http://www.cse.unsw.edu.au/~gregm/secret/ssdi/lectures/