At 02:19 PM 1/15/2008 -0800, Guido van Rossum wrote:
While I have you, I've come across a need that I don't know how to do with GFs. Suppose I have a GF that implements some recursive function over container types, e.g. serialization or flattening. Now suppose I'd like to create *another* GF that implements the same algorithm except it does something different for one particular type; as a concrete example, suppose we want to treat tuples atomically when flattening. Is there a way to reuse the work of the first GF?
Yes. RuleDispatch actually has a 'clone()' feature for single-dispatch generics that does exactly what you're looking for: http://peak.telecommunity.com/DevCenter/VisitorRevisited (see the heading "Extension and Reuse"). It's probably not a bad idea to put a cloning feature on my extended to-do list for PEAK-Rules. In PEAK-Rules (the system after which PEP 3124 was modelled), a generic function has a RuleSet that contains its rules, and RuleSets can be subscribed to. So, you could create a listener that automatically takes the rules added to one function and adds them to others. It's not packaged as a convenient decorator or anything, but one certainly could make one. It'd also need to have some way to ensure that the rules from the original function were treated at a lower combination precedence than anything else, but that could be handled by with a custom method type pretty easily, I think. All in all, a cloning feature might be somewhere around 20-50 lines of code to add in -- and a third party could probably roll their own without changing PEAK-Rules' source.
It doesn't work to create a new GF that calls on the first GF for types it doesn't understand; e.g. a list could contain a tuple. Does your GF machinery let me do this in a relatively clean way?
It's relatively clean. One of my goals for the changed architecture in PEAK-Rules vs. RuleDispatch was to make it possible to do all sorts of things like this, by opening up the whole thing to extensibility. Btw, a lot of the credit for PEAK-Rules' design goes to you, in a roundabout way. Your tuple-of-types prototype made me see that it could be practical to implement generic functions using generic functions as a base -- getting rid of interfaces and adaptation altogether. I just needed to come up with a design that allowed separating the genericness of a function (e.g. the rules to be applied) from the implementation of genericness (the "engine" that turns rules into executability. In this way, a generic function can start out using just tuples of types, but then graduate to a full expression-based system, just by changing the engine.
participants (1)
-
Phillip J. Eby