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.
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@rt t@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.