[Python-3000] Adaption & generic functions [was Generic functions]

Alex Martelli aleaxit at gmail.com
Wed Apr 5 07:01:31 CEST 2006


On Apr 4, 2006, at 9:03 PM, Guido van Rossum wrote:
    ...
> It would be useful to compare this to adaptation built on top of
> generic functions. Alex seems to be convinced that adaptation is more
> powerful than generic functions; but he hadn't considered the
> possibility of having a generic function that's a factory (like the
> iterator-factory in my example). I don't know if that affects his
> opinion though; he seems to find it important that adaptation can
> return an object that has multiple methods that belong together.

Hmmm, I guess I wasn't very clear in the last part of our talk today  
(well, I _was_ sort of rushing towards a meeting, maybe that excuses  
me;-)...: I _was_ (as in _used to be_) convinced that with generic- 
functions (which I used in Lisp and Dylan, but those are languages I  
only played around with -- I never had my income depend on developing  
code in them, except for a short time at my first job, and that was  
_before_ Common Lisp and CLOS existed!-) you had to "manually" keep a  
bunch of related function together, basically like when simulating  
OOP in a pure functional language (without a facility such as  
Haskell's typeclasses to group things up).

I thought I had made it clear that the "flash of obviousness" about  
being able to use a generic function that's a factory had converted  
me on the road to Damascus.

It IS now obvious to me that anything I can express as:

pFoo = Protocol('foo')
class FooFromInt(object):
    def x(...):
    def y(...):
pFoo.register_adapter(int, FooFromInt)

    ...

def zz(z):
     z = pFoo.adapt(z)
     return z.x()+z.y()


I could almost-identically express as:

gFoo = GenericFunction('foo')
class FooFromInt(...as above...)
gFoo.specialize(int, FooFromInt)

    ...

def zz(z):
     z = gFoo(z)
     return z.x()+z.y()


...or whatever small syntax/semantics variations on either or both of  
protocols and generic functions one might wish.  The two "framings"  
of the issue -- protocols carrying their specific mappings of types- 
to-adapter-callables, generic functions specializable by-type on a  
single argument -- are deeply isomorphic.

Framing things in terms of generic functions and their specialization  
may well have conceptual advantages, such as a more natural,  
intuitive way to provide a "default" implementation for any other  
type, than registering an adapter for type 'object' would be with  
adaptation; or making it more obvious and direct to deal with the  
most frequent case, where all you ever need to call on objects  
satisfying protocol x is one single method (in that case, just use  
the generic function for the purpose, rather than making the genfunc  
a factory).

Also, we avoid seeing "adaptation" spelled "adaption", which I've  
already seen happen;-).

This being the case, I'm perfectly happy to sacrifice PEP 246 in  
favor of such generic functions, since I am now convinced that I can  
cover every use case of adaptation with genfuncs.  Using genfuncs  
also kills any issue of "transitivity" since there's obviously no  
place to fit it, which doesn't faze me one bit;-).

How genfuncs could be used as decorators (hopefully to decorate  
_classes_ too, since they're the easiest and most natural way to make  
factories;-), whether multimethods should be such (dispatching on the  
type of _multiple_ args) and how to reconcile that with inheritance  
((I like Philip's idea that, if we go to multiple dispatch, it should  
be an error unless ONE specialization strictly dominates all  
others)), etc, etc, all are questions that are important and deserve  
discussion, but maybe these discussions would be more meaningful in  
the context of some "temporary working Pronouncements" such as "let's  
talk generics and forget adaptation until further notice", I think.

> this. For general Python protocols I don't think it's necessary. For
> that matter, after reading Alex's seminal post, I don't see any reason
> why protocols should have anything to do with interfaces (although
> it's fine for some framework's interfaces to be protocols).

And there was much rejoicing in Alexland!-)


Alex




More information about the Python-3000 mailing list