[Python-3000] PEP 3124 - Overloading, Generic Functions, Interfaces, etc.

Phillip J. Eby pje at telecommunity.com
Fri May 11 20:51:12 CEST 2007

At 01:27 PM 5/11/2007 -0400, Jim Jewett wrote:
>So how is an Around method any different than a full concrete
>implementation?  Just because it has higher precedence, so it can win
>without being the most specific?


>Could you drop the precedence stuff from the core library, and just have
>"here is how to register a concrete implementation"
>"here is the equivalent of super -- a way to call whatever would have
>been called without your replacement"
>I understand that the full version offers more functionality, but it
>is also more complicated.  Maybe use that fuller version as a test
>case, and mention in the module docs that it is possible to create
>more powerful dispatch rules, and that there is an example
>(test\test_generic_reg  ?), with even more powerful extensions
>available as PEAK.rules (http:// ...)  and Zope.Interfaces

I don't have a problem with moving method combination (other than the 
super()-analogue) and aspects to a separate PEP for ease of 
understanding, but the implementation is pretty much the smallest 
indivisible collection of features that still allows features like 
those to be added.  (See the other PEP 3124 threads for that discussion.)

I think this is analagous to PEP 252 and 253, in that their 
implementation is interdependent, but could be considered separate 
topics and thus easier to read when separated.

> > >Library 1 and Library 2 both register Sage classes with Numpy, or vice
> > >versa.  Library 1 and 2 don't know about each other.  Library 1 and 2
> > >also go through some extra version skew pains when Sage starts
> > >registering its types itself.
> > Seriously though, it seems to me that registering third-party types
> > in fourth-party generic functions, from *library* code (as opposed to
> > application code) is unwise.  I mean, you're already talking about
> > FOUR people there, *not* counting Library 2!  (i.e., Sage, Numpy,
> > Library 1, and the user).
>Those are all math libraries; Library 1 and Library 2 *should* both
>work well with both NumPy and Sage, and can reasonably be considered
>extensions of both.
>Saying "You can do this with most numbers, but not NumPy numbers" is ugly.
>Saying "You can do this, but sometimes it will break because the
>extensions I work with don't know about each other, and I won't
>translate, as a matter of policy" is ... probably not going to happen.

If L1 defines a generic function, it's fine for it to register Sage 
and NumPy types for it.  But if NumPy defines a generic function and 
Sage defines the type, how is it any of L1's business?

>Ideally, NumPy and Sage would make the introductions directly, or
>there would at least be a canonical mapping somewhere that Libraries 1
>and 2 could agree on ... but that won't happen at any specific time.

Again, nothing stops L1 and L2 from subclassing those types, and 
registering only those subtypes.  Or from offering *optional* 
registration support modules, so an application can *choose* to 
import them.  NOYB ("none of your business") registration should only 
be done by applications, if they're done at all.

>Saying "You need to upgrade to at least version Package A version
>2.3.4 and Package B version 4.3 to use my code" is unlikely to happen;
>you yourself still support Python 2.2 in your own packages.

2.3, actually, as it's the Python used by the most 
widely-available/supported Linux distros at the moment.

>  > anyway, and the user could, if he/she had to, use multiple
> > inheritance plus some additional registrations of their own to 
> work things out.
>If there are two registrations for the same selection criteria, how
>can the user resolve things?

With an @around method, or by creating and using subclasses.

>Either the first one registered wins, or
>the second, or the user sees some sort of import failure, and can't
>fix it without modifying somebody else's code to avoid one of those

AmbiguousMethods is a call-time error, not a definition time error, 
unless you are using custom combinators.  L1 and L2 would have to 
define their own @lib1 and @lib2 combinators, and register them both 
with the same generic function *and* the same types, before you could 
get a definition-time error.

And I could probably change the implementation to avoid this by 
always deferring method combination until the function is invoked at 
least once, but I'm not convinced it's worth it, especially since it 
could make other errors harder to find when writing combinators.  In 
my experience, most combinators are defined by the library that 
defines the generic function using them, or else are general-purpose 
AOP-ish combinators like @before/@after/@around.

More information about the Python-3000 mailing list