[Python-3000] pep 3124 plans (original) (raw)

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