Python And Ruby Are Converging

RubyLanguage and PythonLanguage often take ideas from each other.

Ruby:
 def foo(a, b=default, *rest)
...
 end
Python:
 def foo(a, *rest, b=default):
...
Python's generators allow you to mix calls to more than one generator at a time and in Python 2.5 more coroutine features have been added to allow the caller to send values to a generator, raise an exception in the generator, or terminate it.

Ruby's internal iterators may be chained through several calls: array.find { |x| x.even? }.map { |x| x + 2 }.sort_by { |x| x % 5 }

Python uses "generator expressions" to perform iterative inline operations: sorted((x+2 for x in array if x%2 == 0), key=lambda x: x%5)

for <vars> in <object> [: | then]
which is identical to the pythonic
for <vars> in <object>: 
open('sorted.txt','w').puts open('in.txt').sort
But now classes like sorted allow you to write in PythonLanguage:
PrivoxyWindowOpen('sorted.txt','w').writelines(sorted(PrivoxyWindowOpen('in.txt')))
for line in open('foo.txt'): do_stuff(line)
which RubyLanguage supported since the beginning.

This could also be written in Ruby as:

File.open('foo.txt').each do | line | do_stuff(line) end
Or:
File.foreach("foo.txt") { |f| do_stuff(f) }


While they may be converging superficially, Ruby and Python's library and user community are moving in very different directions.

Rails is a great example of the RubyWay, which is utterly dynamic in both typing and behavior. Python and Ruby are languages competing for a similar bracket, so they will always appear to be "converging," because smart people are finding the key features. But the philosophy of each language, and the way the community uses them, are utterly different.

Python is moving in a direction where the "ideals" are captured by the decisions made in by GVR. The PythonLanguage additions and modifications are often taken from other languages but are carefully rethought and reworked through discusion and research to represent the concensus of "The best/clearest way to solve this problem". This allows many programmers to share code that "feels" similar, despite having different authors.

[[ Substitute Python -> Ruby and GVR -> Matz in the above, and the statement would still hold, IMHO ]]


A lot of the features have really converged in the new BooLanguage. Boo has a Python syntax but supports LexicalClosures/AnonymousMethods and optional explicit StaticTyping declarations.


This is a bunch of hooey.

The unification of int and long started with 2.0.

Java has BigDecimal; is it also converging? All languages support strings - they must be the same language!

Python's __iter__ protocol is not the same as Ruby's code block approach. For example, in Ruby I can make new control flow through code blocks, while in Python I cannot make new syntax.

The "with" statement in PEP 343 has *nothing* to do with code blocks. It's new syntax for a very limited scenerio (resource management) where code blocks easily provide a more general implementation space.

Well before the __iter__ protocol you could do

for line in open('foo.txt'): do_stuff(line)
with a wrapper which implemented __getitem__ correctly, as

class Iter:
def __init__(self, callable, sentinel=None):
self.callable = callable
self.sentinel = sentinel
self.at_end = 0
self.counter = 0
def __getitem__(self, i):
if self.at_end: raise IndexError
if i != self.counter:
raise AssertionError("forward iteration only")
x = self.callable()
if x == self.sentinel:
self.at_end = 1
raise IndexError
self.counter = self.counter + 1
return x

for line in Iter(open('foo.txt').readline, ""): do_stuff(line)
I think this works even back to Python 1.0. The advantage is the iter protocol doesn't overload __getitem__, which has the expectation of being random access. That is, open("foo.txt")[5] shouldn't look like it would work and return the 6th line of the file. !


CategoryPython CategoryRuby CategoryComparisons


EditText of this page (last edited February 4, 2012) or FindPage with title or text search