Confessions of a Python fanboy

Masklinn masklinn at masklinn.net
Thu Jul 30 07:36:49 EDT 2009


On 30 Jul 2009, at 06:04 , alex23 wrote:
> On Jul 30, 1:06 pm, r <rt8... at gmail.com> wrote:
>> 1.) No need to use "()" to call a function with no arguments.
>> Python --> "obj.m2().m3()" --ugly
>>   Ruby --> "obj.m1.m2.m3"  -- sweeet!
>> Man, i must admit i really like this, and your code will look so much
>> cleaner.
>
> How do you distinguish between calling a method with no arguments, and
> getting access to the method object itself (because it _is_ an object,
> y'know, it's OO all the way down...)?
>
As chris pointed out, there's a method for that, to which a symbol is  
provided: `Object#method(methodname)`, which is basically equivalent  
to `getattr(object, methodname)` in Python.

>> 2.) the .each method
>> container.each{|localVar| block}
>> This method can really cleanup some ugly for loops, although i really
>> like the readability of for loops.
>
> map(lambda localVar: <block>, sequence)
>
> or:
>
> def usefully_named_func(var):
>    <block>
>    return var
>
> transformed = [usefully_named_func(v) for v in sequence]
>
The issue here is of course that `map` and comprehensions are  
transformations. `#each` exists for effectful iterations (Ruby has  
`#map` for the map operation). So the intent expressed by `#each` and  
`map` isn't the same. Furthermore and this is the most problematic  
limitation of Python here, `lambda` doesn't allow complex  
transformations due to its restrictions, so one has to switch to named  
functions which works but isn't sexy (and tends to lower readability  
imo).

>> 3.) true OOP
>> Now before you go and get all "huffy" over this statement, hear me
>> out. Python is the best language in the world. But it damn sure has
>> some warts! "len(this)" instead of "obj.length" max(that) instead of
>> [1,2,3,4,5].max().
>
> As the Zen says: '[P]racticality beats purity'. Personally, I'm not
> sure how a handful of convenient built-in functions make a language in
> which _everything is an object_ somehow "false" OO.
>
That's an interesting point, but not relevant at the end of the day:  
`foo.length` and `length(foo)` have the same "practicality". On the  
other hand Ruby can be praised for the coherence: everything's a  
method period end of the story; while Python does have a dichotomy  
between methods and functions/generic methods (whether or not that  
dichotomy bothers users is another issue).

> With max(), this is a built-in that takes _any_ iterable and an
> optional key function, and returns the highest value as per the key.
> This means that _every_ iterable object - as _well_ as every object
> that supports enough of the iterator protocol - can be handed to max()
> and a result obtained. So at best, I just need to make sure my new
> sequence-type provides the iterator protocol and viola, it works with
> max() without me having to hand-code a .max() that's specialised for
> my new type, and without Python forcing me to have a complex
> inheritance chain just to make sure I include the right
> MaxableSequence ancestor to inherit the right .max().
>
Well interestingly, Ruby works pretty much the same way. Where Python  
asks that you implement the iterator protocol to have `max` work, Ruby  
asks that you implement the `each` method (also called the Enumerable  
protocol) and mixin `Enumerable` (http://ruby-doc.org/core/classes/Enumerable.html 
). Then you get max (and min, map, etc…) "for free". Of course you're  
free to re-implement all of them manually if you wish to do so (or if  
you need those operations to return your custom collection rather than  
arrays). Enumerable is merely a convenience mixin. So there's no big  
difference here (and note that mixins aren't necessarily part of the  
inheritance chain, though they're implemented that way in Ruby).

Also, it's "voilà" not "viola" (a viola is a bowed string instrument,  
slightly bigger than a violin, whereas voilà is a french interjection  
used to call attention or suggest the appearance of something, as if  
by magic).

>> PS stay tuned for more from this series....
>
> Is this going to be more of you telling us - without any apparent
> irony whatsoever - how Ruby has some valid points after all your
> vilification last year when we said the same to you?  If so, where can
> I sign up?!
I fear I'll have to agree with that sentiment.


More information about the Python-list mailing list