A foolish consistency, etc
People new (and not so new) to Python are often confused by the fact that the language uses functions in some situations, but methods in others. I see this come up a lot these days. The most recent example is this comment:
Say you have a list, how is a beginning supposed to follow/comprehend the bigger picture when faced with code like this:
mylist = [1,3,2] print len( mylist ) print sorted( mylist ) print mylist.sort() print mylist.reverse() print mylist[0]Honestly, what is going on here? Why different syntaxes for slightly different ideas?
This gives many people the feeling that OO in Python was added later, or "bolted on", as Taw puts it.
I figure the reasons for the discrepancy are like this:
In 1991, when Python was first released, *pure* object-oriented languages were rare. Sure, there was Smalltalk, but it was fairly obscure. Other languages that called themselves object-oriented, like C++ and ObjectPascal, were actually hybrids; objects were indeed "bolted on" to an existing language.
In this light, it makes sense that Python 0.9.1 did the same. It had built-in types, and user-defined objects. Some of the types, like lists and dictionaries, had methods, possibly because were mutable and therefore contained "state". Other types, like numbers, strings and tuples, did not have methods (and were therefore not "perceived" as objects, even though behind the scenes they were). (In fact, back in the early 90s, the idea of calling a method on a number seemed like a really odd idea (if you were not a Smalltalker :-).)
As a result, in order to take the length of a string or a tuple, you needed a *function* (because you could not call a method on these types). While list and dict could easily have had such a method, for consistency's sake this was omitted; instead, the len() function was to be used on them too.
And so it still is. But the world has changed since then. OO has become much more mainstream, and the notion of using methods for everything is no longer odd, but expected by many. I can understand why someone coming from Ruby (or maybe Java) would wonder why in some cases functions are required, where a method would seem more natural. It makes Python seem inconsistent, when initially the use of len() actually improved consistency.
This is something that *could* have been fixed in Python 3.0, but won't, as far as I understand it. I'm not sure if this is a missed opportunity, or that it will keep Python closer to its original spirit (i.e., a multi-paradigm language).
(Note: I am aware of the __len__ method of course, but honestly, who is really going to use that instead of len()? __len__ is a hook to make len() work, not an alternative for it.)


