[Python-3000] Special methods and interface-based type system

Guido van Rossum guido at python.org
Thu Nov 23 05:29:54 CET 2006


On 11/22/06, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Guido van Rossum wrote:
> > I chose len(x) over x.len() for HCI reasons
> >
> > (a) For some operations, prefix notation just reads better than
> > postfix
> > (b) When I read code that says len(x) I *know* that it is asking for
> > the length of something.
>
> Just as a matter of interest, how far do you
> think these principles apply or don't apply
> to more recent things like iter.next() that
> don't follow this pattern?

it.next() isn't something one does commonly; it's mostly implied by
the for-loop. iter(seq) which was invented at the same time *is* a
prefix op.

There's probably a somewhat better rule hiding in all this; something
that explains why keys() is a method. Perhaps it depends on the
generality of the operation -- keys() is pretty unique to mappings,
while len() and iter() apply to all containers. Similarly, next() only
applies to iterators (even if there are about as many iterators as
their are containers, they all have the same API). I guess the chances
that something becomes an "operation" are better if it applies to a
wide variety of types (that have otherwise different interfaces,
unlike iterators which all have the same interface).

Interestingly, keys() being a method makes it pretty much impossible
to turn it into a generic function. This doesn't seem a big loss, it's
unlikely one could implement it easily for a mapping type that doesn't
provide keys() natively. OTOH, values() and items() could be
implemented easily for anything that has keys() and __getitem__() (or
iterkeys() and __getitem__()). But it's also easy to write an app
without using values() and items() (using keys() and __getitem__()) so
this is still not a big deal.

One thing that rubs me the wrong way about generic functions is that
it appears to go against OO. Now I'm not someone to take OO as
religion, but there's something uncomfortable (for me) about how, in
Phillip's world, many things become functions instead of methods,
which brings along concerns about the global namespace filling up, and
also about functionality being spread randomly across too many
modules. I fear I will miss the class as a convenient focus for
related functionality.

While [@]defop moves the operation definitions back into the class,
the invocations still takes the form of a function call. We could end
up with two different mainstream notations: foo(x) and x.foo(), and
which one is used for a particular operation is the result of a very
subtle decision process that takes into account different evolution
and/or usage patterns for the classes involved (as is shown by the
difficulty we've had explaining why len() and iter() are functions but
next() and keys() are methods, for example). Of course Python always
had functions and methods, but the choice used to be so much simpler
before generic functions: a function has a single implementation, a
method can be overridden. I will miss that simplicity.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-3000 mailing list