[Python-3000] pep 3124 plans
Phillip J. Eby
pje at telecommunity.com
Fri Jul 20 19:45:54 CEST 2007
At 07:49 AM 7/20/2007 -0700, Guido van Rossum wrote:
>On 7/19/07, Joe Smith <unknown_kev_cat at hotmail.com> wrote:
> > So the state of the PEP? From the rest of the posts so far,
> > it sounds like there is no real objection to the basic end user API as
> > described in the PEP,
>
>Actually I want to reserve judgment on that until the PEP is rewritten
>to explain and document the underlying mechanisms. It is currently
>impossible (for me, anyway) to understand how the machinery to support
>the described features could be built. Without that I cannot approve
>the PEP. Phillip knows this but is too busy to work on it.
Actually, I was under the impression you didn't want the API
described in the PEP, and wanted the following changes in addition to
dropping method combination, aspects, and interfaces:
* :next_method as a keyword-only argument
* @somegeneric.overload as the standard decorator (w/no @overload or @when)
* advance declaration of a function as overloadable (which is also
required by the previous change and by your preference not to modify
functions in-place)
Also, I didn't know you wanted an explanation of how the underlying
mechanisms work in general. I thought the only piece you were
looking for more explanation of was the method combination machinery
-- which would be moot if we're scaling back the API as described by the above.
Just to be sure I'm clear as to what you want, is that the only
mechanism you're unclear on, or is the whole thing unclear? The
whole thing was inspired by your overloading prototype, I've just
made all the concrete bits of it more... "generic".
That is, instead of using issubclass or other explicit relationship
tests between overload signatures, I use a generic function
implies(). Instead of simply storing a method added as an overload,
I use a "combine_actions()" generic function to combine it with any
method that's already there (possibly including a method type for "No
Method Found"). Instead of simply finding the most-specific matching
signature on cache misses, I use combine_actions() to combine *all
applicable* actions (i.e., all those that the calling signature implies()).
The combine_actions() function uses another generic function,
overrides(), to compare method priorities. overrides() is defined so
that Around beats Before beats After beats regular methods beats no
method found. The overrides() of two methods of the same type is
determined by which signature implies() the other, without also being
implied *by* the other.
If there is no overrides() order between two methods, you get an
AmbiguousMethod combining the two -- which can be overridden by any
method whose signature implies() everything in the AmbiguousMethod.
All this is pretty much the same as in your prototype, except that
it's done by adding these rules to the generic functions, rather than
by hardcoding them. That's why it's bigger than your prototype, but
also why it's extensible in terms of adding new method types or ways
to specify signatures.
I then also added the ability to attach different dispatchers to a
function, so that you could replace the simple "tuple of types"
matching with more sophisticated engines like RuleDispatch's, while
still retaining the ability to use the same method combinations and
existing overloads registered for a function.
That is, it lets you keep the same API for defining overloads and
method combinations as the basic implementation, while allowing the
actual overload targets and dispatching mechanisms to vary.
That's pretty much it except for Aspects and Interfaces. I've ended
up making my Aspect implementation available separately in the
ObjectRoles cheeseshop package, renaming them Roles instead of Aspects.
(And yes, I will add all the above explanation to the PEP.)
>AFAIK Phillip has declared that his implementation only uses (or could
>be made to only use) isinstance()/issubclass(), and the overriding of
>these two used by the ABCs is actually very convenient for the GF PEP.
Yep. The overload of "implies(c1:type, c2:type)" is
"issubclass". "isinstance()" isn't used, since that would render
your type-tuple caching strategy unusable.
More information about the Python-3000
mailing list