Method Underscores?

Dave Benjamin ramen at lackingtalent.com
Tue Oct 26 01:18:04 EDT 2004


> "Chris S." <chrisks at NOSPAM.udel.edu> wrote in message 
> news:9dIdd.3712$EL5.3057 at trndny09...
>> Is there a purpose for using trailing and leading double underscores for 
>> built-in method names? My impression was that underscores are supposed to 
>> imply some sort of pseudo-privatization, but would using myclass.len() 
>> instead of myclass.__len__() really cause Python considerable harm? As 
>> much as I adore Python, I have to admit, I find this to be one of the 
>> language's most "unPythonic" features and a key arguing point against 
>> Python. I've searched for a discussion on this topic in the groups 
>> archives, but found little. What are everyone's thoughts on this subject?

Wow. To me, the double-underscores is one of the most Pythonic things I can
think of. I don't believe that "Pythonic" means "good", at least not in my
book. But it's definitely one of Python's birthmarks.

I think len() is really cool. It's short, it's generic, and it's consistent.
It's not object oriented, of course. I don't believe that "object oriented"
means "good" either. But then, the OO way doesn't really make sense anyway.
Why would you send the list a "size" message, and have it respond to you,
"5"? That's silly. Lists don't talk. You want the size, you "take" it.
len(L) says "take the length of 'L'". Now, that's better.

The other great thing about len() is that it's the same for all collections.
Sure, there's nothing to stop you from implementing ".len()", or ".size()",
or ".numberOfElementsInsideOfMe()", but why would you? You've already
learned Python, you know that "len" takes the length of something, and you
certainly don't want to confuse yourself. Why not just implement the
protocol? What's it called? Of course... this is Python... must be those
double-underscores, right?

Contrast this with Java's ".size()", ".length()", ".length", etc. How would
you write a generic function to consolidate them all? You'd have to write
one overloaded method to take a Collection, another to take an Object[], and
so on down the line. If the class has an interface, you're lucky. Otherwise,
it's time to use reflection. Bleah. I'll take Python over this any day.

Although Ruby, I think, gets this right, so not all OO implementations are
flawed in this respect.

In article <10ngmuq11n9qn97 at news.supernews.com>, John Roth wrote:
> Languages that make everything methods tend to have
> two characteristics in common: a single base class, and
> no facility for procedural programming.

The only languages I could think of that match this criteria are Ruby,
Smalltalk, and Java. Are there others I've missed?

> Python does not have a single base class, and one of its
> strong points is that it's a multi-paradigm language. You can
> use it for procedural programming without having to put
> everything in the object paradigm. People quite frequently
> do this for scripts.

Exactly. And a lot of people learn Python starting with algebra (I know
several non-Python programmers that use Python as a desk calculator), and
then move on to procedures, and then finally master objects. Python lets you
get pretty far without having to send messages to thingies. You can rely on
things you probably already know, like math. One of the things that I love
about Python is that it doesn't try to be a pure-OO language. It does OO,
and does it rather well, I think, but sometimes you just have to write a
couple of functions and run, and Python acknowledges that.

> In single base class languages, the top object in the
> hierarchy is a hod-podge of methods that have no
> relationship other than the language designer's decision
> that the function is fundamental enough that it needs to
> be available to every object, whether it needs it or not.

It depends on the language. Java's Object has a pretty small number of
methods, although some of them seem rather inappropriate. I don't know if
it's fair to call Java a single base class language, though, since it has
types that support operators and not methods (and Arrays, which fall
somewhere in between). In any case, I recall proclaiming to a Java-loving
coworker one day, "Object should have a 'length' method!". He thought it was
the dumbest idea ever, but the reason I mentioned it is that I was thinking
to myself, "Gee, it's so nice that I have one way to get the length of
anything in Python. If Java only put a 'length' method on Object from the
beginning, it probably would have been more consistent." The only other way
I could see pulling this off would be to make an interface for everything
Lengthable, and hope people remember to implement it, or switch to a
structural typing system and get the statically-typed version of what Python
already does easily.

> It would be technically possible (and relatively easy for
> anyone with a bit of experience with working on Python's
> internals) to add, for example, .len() to the object class.
> Would this break anything? Unlikely in most cases
> (there is one edge case I know of where it would).  Alex Martelli's
> comment elsewhere in this thread assumes one would also
> remove it from the builtins, which would of course break
> everything in sight.

And if you don't remove it, then TMTOWTDI, which means that Guido will turn
into a pie and we will all lose our minds and $t at rt t at lk1ng l1k3 th1s!11!!!

> Removing it from the builtins is equivalent to eliminating
> the multi-paradigm nature of Python: you could no longer
> do effective procedural programming without the builtins!
> This is simply not going to happen: it would be a completely
> different language. Discussing it is futile.

The builtins are great. Every language should have a basis library. To do
otherwise is to overengineer, to favor namespace elegance over practical
usefulness, and to demote functions and procedures to being second-class
citizens. The basis is what gives a language its character. It's like slang.
Nobody likes a society with no slang at all. We want a slang we like. And
Python's got a pretty good one, I think.

> Also, the new .len() method would only be available
> to new style classes written in Python, and then only
> if the author of some subclass had not decided to implement
> their own len() method with different semantics. The
> first of these two objections goes away in Python 3.0,
> where old style classes are eliminated. The second,
> however, is a difficulty that all "pure" OO languages
> need to deal with, and there is no real good way of
> handling it (meaning obvious, works all the time
> everywhere, and upward compatible without breaking
> anything.).

IOW, a complete waste of time.

> Having a parallel structure where a large number of
> builtins are also implemented as methods on object
> violates Python's basic philosophy in at least two
> ways: there should only be one (obvious) way to do
> something, and things should work the same way
> everywhere.

Well, technically, you can call L.__len__() today, so there are two ways to
do it. You could also write a loop with a counter, or turn it into a string
and count the commas. But none of these are *obvious* ways, and I think that
the *obvious* is what makes that "law" really mean something. To a Java
programmer, "len()" may not be obvious, but once you learn it, it really
can't get any more obvious. I remember my delight when PythonWin
automatically supported "len()" on COM collections, and my dismay (and
motivation to fix this deficiency immediately) when I discovered that
Jython+Jintegra didn't. In COM-land, they say ".Count()", and they probably
don't have an interface for it either. ;)

> All that said, I'd like to see some of the builtins
> as methods on object, but since it's not going
> to happen, it's not worth worrying about.

Really? Which ones?

I'd like to see map and filter be built into sequences, and I suppose "id()"
would make sense on Object, but I really can't think of any others I'd change.

-- 
 .:[ dave benjamin: ramen/[sp00] -:- spoomusic.com -:- ramenfest.com ]:.
        "talking about music is like dancing about architecture."



More information about the Python-list mailing list