[Python-3000] Generic function PEP won't make it in time

Phillip J. Eby pje at telecommunity.com
Thu Apr 26 22:08:25 CEST 2007


At 09:00 AM 4/26/2007 -0700, Talin wrote:
>I kind of wonder about the idea of implementing generic functions using
>generic functions. It's one of those ideas that is so obviously elegant
>and clever, that it's very easy for a programmer to fall in love with.
>As someone who frequently finds himself in a similar situation, I often
>discover later that the clever idea I loved wasn't the most practical.

In this case, it's the reverse; I previously implemented generic functions 
the other way around, in RuleDispatch.  PEAK-Rules is considerably simpler; 
in fact I've been realizing lately that the more "object orientation" I 
*remove* from it, the easier it gets to work with.

For example, it's recently become clear that my "TreeBuilder" class (used 
to assemble efficient dispatch trees by figuring out what tests come next) 
is nothing more than a memoized generic function.  Having the class exist 
just adds to the number of things you have to subclass when you change 
anything, and makes it more complex because you also have to change any 
code that *creates* a TreeBuilder to create an instance of your subclass 
instead.  Making it a generic function makes  a bunch of extra bookkeeping 
just disappear.


>Now, I may be talking out of my butt here - I don't know much about your
>situation, or what rationales you have for designing things the way that
>you have.

Pretty simple, really -- RuleDispatch's heavily object-based internal 
structure made it brittle and complex to refactor or extend, compared to 
the outer layers where it used generic functions.  The obvious solution was 
to make the inner layers generic also.

The real key, though, was looking at Guido's "overloading" prototype for 
Py3K and realizing I didn't need to settle for single-dispatch generics for 
the core, or have to try and bootstrap the engine on itself; I could use a 
simple implementation like his that did multi-dispatch instead.  And so I did.

After some experimentation, I found that you can make any generic function 
self-bootstrapping (i.e., usable in its own implementation) as long as your 
implementation is re-entrant.  That is, if a generic function has to call 
itself while a method is being added to it, it must simply call the *last 
stable version* of itself, rather than the version it's modifying.  This is 
actually quite simple to arrange, even in the presence of threads.


>However, I would suggest that you might want to consider what
>your actual, practical needs are, and if there is a way to get them that
>is more straightforward and easy to explain.

Well, I could use some other language of course, but I prefer Python.  :)



More information about the Python-3000 mailing list