[Python-3000] pep 3124 plans

Phillip J. Eby pje at telecommunity.com
Wed Jul 18 02:27:02 CEST 2007


At 03:53 PM 7/17/2007 -0700, Guido van Rossum wrote:
>On 7/17/07, Phillip J. Eby <pje at telecommunity.com> wrote:
> > At 02:47 PM 7/17/2007 -0700, Guido van Rossum wrote:
> > >I have one remaining question for Phillip: why is your design
> > >"absolutely dependent on being able to modify functions in-place"?
> > >That dependency would appear to make it harder to port the design to
> > >other Python implementations whose function objects don't behave the
> > >same way. I can see it as a philosophical desirable feature; but I
> > >don't understand the technical need for it.
> >
> > It allows the framework to bootstrap via successive
> > approximation.  Initially, the 'implies()' function is just a plain
> > function, and then it later becomes a generic function.  (And of
> > course it gets called in between those two points.)  The same happens
> > for 'disjuncts()' and 'overrides()'.
>
>Why isn't it possible to mark these functions as explicitly
>overloadable?

How would I ever add rules to them, if I need them to already be 
callable in order to add any rules in the first place?  :)  (In 
practice, things are even hairier, because I also sometimes need to 
call these functions *while they are already being called*, if 
there's no cache hit!)

This is partly a consequence of splitting responsibilities between 
"rule sets" and "dispatch engines".  PEAK-Rules wants to be able to 
use a simple type-tuple dispatcher (like your prototype), but also 
upgrade to fancier engines as required for specific functions, 
without changing the rules already registered for the function.  So 
it treats the set of overloads as a separate object from the engine 
that actually implements dispatching.  That way, you can upgrade the 
engine, even while keeping the rules.

However, to populate a rule set, you need to know the disjuncts() of 
a rule...  so you could never add the default rule to disjuncts() 
without a default rule already being there.

None of this is relevant for a design that doesn't care about having 
more than one supported implementation, though, which is why a 
reduced-in-scope implementation that's not trying to be a universal 
API can just ignore all of this.

(Heck, disjuncts() wouldn't even be needed in an implementation that 
wasn't trying to support arbitrary engine extensions, since its 
purpose is to list the "or"-ed conditions of a rule that can be 
fulfilled in more than one way.)


> > Well, the one thing that might still be relevant is the "overloading
> > inside classes" rule.  That's the only bit that has any effect on
> > Python 3.0 semantics vis-a-vis metaclasses, class decorators, etc.
> >
> > The way things currently stand for 3.0, I actually *won't* be able to
> > make a GF implementation that handles the "first argument should be
> > of the containing class" rule without users having an explicit
> > metaclass or class decorator that supports it.
> >
> > In 2.x, I take advantage of the ability of code run inside a class
> > suite to change the enclosing class' __metaclass__; in 3.0, you can't
> > do this anymore since the __metaclass__ doesn't come from the class
> > suite, and there isn't a replacement hook.
>
>I don't understand enough of your implementation to understand this 
>requirement.

This part would actually be relevant even for a scaled-down 
non-extensible implementation.

The requirement is this: overloads defined in a class need to 
implicitly treat the first argument of the overloading method as if 
it were explicitly declared "self: EnclosingClass".

In order to do this, the equivalent code in RuleDispatch currently 
sticks a temporary metaclass into the class locals(), so that it can 
defer the overload operation until after the class exists.  Then it 
adds in the class to the overload registration.

This could be handled by any other sort of mechanism that would allow 
code in a class body to register a callback to receive the created 
class.  A custom metaclass or class decorator would certainly do the 
trick, but then you have do something like:

      @class_contains_overloads
      class Something:

          @some_function.overload
          def blah(self, ...):
              yadda()

It'd be nice to be able to skip the redundant class decorator, as 
it's not adding any useful information for the reader, and forgetting 
it will produce a bug.  So if method decorators were allowed to 
request class decorators to be added, that would be the simplest way 
to manage this.

However, if this has to wait for 3.1, it's no big deal.



More information about the Python-3000 mailing list