Ian Bicking: the old part of his blog

Fixes What's Wrong With Python

Jim Weirich throws down the gauntlet with Ten Things a Java Programmer Should Know About Ruby: "Fixes what's wrong with Python".

OK, I actually don't care about that dig, I'm in a friendly mood these days. But it's interesting how many of the points are just as true for Python as Ruby; to me this merely confirms that they are extremely similar (and maybe that this post inspired some of the points). Quoting from the list (which no longer numbers ten) here's the few that aren't the same for Ruby and Python (ignoring trivial or syntactic differences). My comments are italic:

Well, for the most part the list is notable in how few differences there are. If you look at this comparison and ignore the points that are out of date, you'll notice that there's a difference in heritage and perspective (Ruby coming from a Smalltalk-OO background), but very little (any?) functional difference besides closures and blocks. And a whole bunch of syntactic differences, but that's neither here nor there.

Created 01 Feb '05

Comments:

I read "An instance of a class can be extended to be subtly different, without needing to subclass" to mean simply

o = Foo() o.nonstandardattribute = bar

# Jonathan Ellis

Yes, I think that's mostly what he means. Also, you can add and override methods in the same way. You can change the class directly -- monkey patching -- or you can create an instance and assign a function to an instance variable to override the method that the class contains. Other uses of first-class functions can accomplish all sorts of things; though honestly how they do that in Ruby (generally) I'm not sure, since it doesn't have "functions" per se, just methods. I get the impression there's some confusion there, with a couple techniques available.
# Ian Bicking

they just write:

def an_instance.amethod(args)
 ...
end

It is a nice way to write stuff since it also allows for clear specification of class/module methods:

class Foo
 # we are in Foo's scope, "self" is Foo
 def foo() puts "I'm an instance method" end
 def self.foo() puts "I'm a singleton method of a Class instance" end
 def self.bar() puts "In java parlance, I'm a static method of class Foo" end
end

(Formatting fixed; I'm not actually the author of this comment)

# Ian Bicking

There's also this:

module Mod
  def hello
    "Hello from Mod.\n"
  end
end
class Klass
  def hello
    "Hello from Klass.\n"
  end
end
k = Klass.new
k.hello       ->      "Hello from Klass.\n"
k.extend(Mod)         ->      #<Klass:0x4018d554>
k.hello       ->      "Hello from Mod.\n"
# Alexander Staubo

"o = Foo(); o.nonstandardattribute = bar"

this can't be done.

attributes in ruby are set via setter methods

class Foo
  def std_attr= v
    @std_attr = v
  end
end

although the simpler way to do it is

class Foo
  attr_writer :std_attr
end

what "An instance of a class can be extended to be subtly different, without needing to subclass" actually means is

s = 'a string'
class << s
  def consonants
    gsub /[aeiou]/i, ''
  end
end

s.consonants will give you " strng", but on any other string, it'll raise an undefined method error.

# caio chassot

I like both Python and Ruby. I agree with your summation that there isn't much to choose between them; except for blocks/closures, but for me that is all the reason I need to choose Ruby. Blocks are an astonishingly[1] powerful tool that transform the way you write code and interact with a system.

Until you have experience of them you probably won't get how powerful blocks/closures are. I'm generalising from me, because I didn't get it for a long time, to you. Probably unfairly.

# Rob Lally

Ack! Ian, sorry about the gauntlet. I didn't actually throw it, more like I accidently bdropped it on the floor.

Last week I asked for suggestions for a "Ten Things Java Programmers Should Know About Ruby" list. The Ta-Da list you linked to is a (temporary) compilation of all the suggestions coming in, without any editting on my part. (Obviously, for the list is a "bit" longer than my targetted goal of ten items). It is there so that people can review all the current suggestions before making new ones. I'm putting together a small presentation for a group of Java programmers and was just soliciting feedback.

Unfortunately, there is no easy place in a Ta-Da list to capture the above meta-information. The list is short-lived anyways, it will probably go away when I've compiled my final version.

For the record, "Fixes what's wrong with Python" does even come close to making the top ten things a _Java_ programmer would need to know. (For that matter, I wouldn't even put it in a list of things a Python programmer would need to know). Ruby and Python are much more similar than different (as you point out), especially compared to what makes it as mainstream languages these days. Your comments on the differences are pretty much right on too.

# Jim Weirich

Although a Java developer wouldn't care, one Ruby feature I'm waiting for in Python is continuations (callcc in Ruby, also available in Stackless Python). Py's generators are a specific kind of (as opposed to a generic) continuation.
# Ken MacLeod

I agree that Python's default string interpolation sucks, but it's simple enough to fix. Just import the sys and Itpl [1] libraries and write sys.stdout=Itpl.filter() to get real string interpolation. Definitely not as clean as native string interpolation, but if that's a deal-breaker for anybody, it's easy enough to fix.

[1] http://lfw.org/python/Itpl.py

# Bill Mill

String interpolation by default is a _bad_ thing. It introduces unexpected behavior which are frequently security holes. Explicit interpolate(string, map) of some sort is better.
# Oliver X

How about writing a "Why Python is better than Ruby" point by point and let Ruby guys respond?
# James

I guess I'd be afraid of lots of "Ruby has that too!" responses, but I suppose if prefaced properly maybe that would be okay. Or it could just go on the Python Wiki, and let collective editing clear out the issues and debate. The Pattern Repository has a page: http://c2.com/cgi/wiki?PythonVsRuby -- but it's not that up-to-date and there's no clear distinction between exposition and discussion.

To me, most of it comes down to some vague design principles: Python emphasizes uniformity, and in this way it's much more like Smalltalk. It also has some different perspectives on how to address the same issues, e.g. loops and first class functions instead of blocks. There's also some things that I have intuitions about, but haven't tried enough in Ruby to confirm. E.g., a traditional procedural perspective makes libraries easier to wrap, and encourages two-level wrapping -- a very thin wrapper that interfaces with C, and another wrapper that provides "Pythonic" abstractions over that library. This is a design technique that I really like; I'm sure people do it in Ruby as well, but I suspect it's not as easy to do the trully thin wrapper in a strict OO world.

There's some other important design issues that I have with Ruby. One in particular is the ways you can globally effect the system, and effect the basic types in the system. Being able to implement (globally and transparently) case-insensitive comparisons of strings is an anti-feature to me. This is an aspect of Smalltalk I dislike.

But the big one for me is the libraries and infrastructure. Python has gained a considerable degree of acceptance, has become part of the standard installation of most Unixy OSes (including Mac OS X), is a first-tier target for open source libraries (there's a lot of C libraries that have Python bindings from day one), and there's a large community of people who have learned how to do interesting and novel things in Python without requiring changes (or even good support!) from the language. Twisted, for example, would have been a lot easier in Ruby, and yet they seem to be doing pretty well despite that. All the really exciting stuff in Python these days isn't in the core language, and yet there's a lot of exciting things happening.

What really discourages me from the comparison and debate is that I don't think there's much to be gained from it. For Python and Ruby to try to take users from each other is a losing game -- we're both small players, and there's much better and bigger pools of developers we should be trying to attract. There's also so much more we can say about why you should use either language instead of Java or C# or what-have-you, compared to why you should use Python instead of Ruby or vice versa.

# Ian Bicking

I looked at Ruby over two years ago. The ugly Perl-like syntax is a definite turn-off, but the deal-breaker for me was multithreading, or the lack thereof. If you think Python global interpreter lock is bad, Ruby's cooperative multithreading is far worse. This may have been fixed in the last 2 years, however.
# Fazal Majid

Surprises me is no ones mentioned unicode, as in Python "does" while Ruby "doesn't" (yet). Kind of a crucial fact that I imagine Java programmers would definately want to know about.
# Harry Fuecks

An excellent point -- it's far more valuable to introduce people to the benefits of dynamic languages than to argue so much about which language to use. And I also suspect that Ruby may have been (and continue to be) a stimulation for Python improvements, as C# has definitely been for Java. Until Ruby, there hasn't been much competition for Python IMO, and now there is.
# Bruce Eckel

Definitely - competition for Python is a good thing. I'm sure everyone's tired of hearing about it, but Rails is of course a recent (loud) example. And it's already sprung up a challenger in Python (Subway). I think it clearly raised the bar in terms of overall "polish", and while often reaching hyperbole, shows the buzz you can get by extensive promotion and attention to detail (docs don't hurt!).

A difference I've noted though as a "consumer" of web frameworks (I'm no genius) is that Rails was very actively promoted - I've not seen any python web framework promoted anywhere near as much (and I don't mean claims of "10x faster"). Zope and Plone are quite well known, but holy learning curve. They almost make J2EE look simple. And Rails was very much designed - after being mostly built on the fly assembling Basecamp - to be packaged and presented as something you should use , whereas most python projects strike me as this works well for us, try it, if you like it great. if not, 'roll your own, it's easy. Or all python devs are so busy they have no time to polish and publicly release/evangelize. Of course I'm broadly generalizing, but I think the broad point is valid... I just often get the sense in pythonspace of "well we know it kicks ass, if you're ignorant enough to not realize it, that's your problem". And that attitude is rarely explicit - it's more often evident in responses to newbies and lack of docs and so on.

I hope this is taken as constructive criticism, 'cause that's how it's meant. I fear sometimes all you guys who write the guts of python and the serious libs are sometimes not aware of the view from the cheap seats (newcomers).

# Todd G

>. Zope and Plone are quite well known, but holy learning curve.

I know this is off topic but one thing I don't get is why people always say the Zope has a huge learning curve. I have never seen a framework that didn't have a learning curve, but comparing zope to J2EE (oh an whatever App server you also need to run your J2EE solution) is being way to unfair on zope. (Have you ever had to set up a tomcat/apache/J2EE/oracle environment, just so you can do some basic persistent web app ;-)

With zope you can be very productive very quickly. The more you use it the more you learn and the greater the sophistication of what you can then do. But you don't have to get into the bowels from day one.

# TIm

Maybe it's the lack of docs. Last time I looked at least. And the near-requirement to setup Squid for any reasonable speed. The big long paper the Quixote guys at MEMS wrote (about why they developed Quixote rather than using Zope) addresses it far better than I ever could.

And getting a java servlet container up and running these days isn't so bad at all. Dropping jar's in is nice too.

# Todd G

"An instance of a class can be extended to be subtly different, without needing to subclass" to mean using something like Delegator or SimpleDelegate. I wouldn't be suprised if python could do something similar, or had a similar mechanism for the pattern.

They also could mean doing something like:

str = ""
puts "Not Moo" unless str.respond_to? "moo"
class String
def moo
      " I AM A SPECIAL STRING I CAN MOO"
end
end
puts "Is moo! " if str.respond_to? "moo"

Extending the availible methods of the class String at runtime, for all Strings

# Ian Bicking

Python has singletons. They are called "modules".

# Michael Tobis