[Python-3000] Adaptation vs. Generic Functions

Tim Hochberg tim.hochberg at ieee.org
Thu Apr 13 19:03:31 CEST 2006


Let me update my original thought experiment in a way that (I think) 
preserves the current behaviour while also requiring strict dominance. 
Let's imagine for a second that we have two new types at the top of the 
hierarchy. I'll call them Ultimate and Penultimate. So the inheritance 
tree goes like:
    Ultimate->Penultimate->type->...

It's weird to have types above type, and Ultimate and Penultimate 
wouldn't necessarily have to be real types, they could just be markers 
that generic treats like types. Still, for the moment let's pretend 
they're types.

Now,

     class Weeble:
         #...
         def __add__(a, b): # ...
         def __radd__(a, b): # ...


gets automagically translated into something like:

     class Weeble:
         #....
     @operator.add.register(Weeble, Penultimate)
     def add(a, b): #...
     @operator.add.register(Ultimate, Weeble)
     def radd(b, a): #...


Now add will be tried before radd naturally and we can still preserve 
strict dominance.

There are issues with this: Ultimate and Penultimate are weird, it 
doesn't extend naturally to more than two args and we still don't know 
how to treat NotImplemented. Plus more that I'm not seeing right now I'm 
sure.

One possibility is that instead of superclasses we have a marker object 
that generic treats specially; let's call it Any. The constructor for 
this object takes an argument that determines the order in which it is 
tried. Thus Penultimate becomes Any(0) and Ultimate becomes Any(1). This 
generalizes to any number of arguments and removes the extra classes 
above type in exchanges for extra complexity inside of generic.

To support NotImplemented you need some way to get the next method. And 
before you do that, you need to agree on what next method means. A 
procedure I floated on Guido's blog to get the next method is to use the 
same machinery used for finding the primary method, but to exclude any 
methods already tried. I believe that this works in the simple case 
above although I'm unsure about its utility in more complex cases.

Regards,

-tim



More information about the Python-3000 mailing list