[Python-3000] Some canonical use-cases for ABCs/Interfaces/Generics
Phillip J. Eby
pje at telecommunity.com
Wed May 2 06:29:06 CEST 2007
Thanks for writing this!
At 08:10 PM 5/1/2007 -0700, Talin wrote:
>Other kinds of transformations would include:
Compilation is a collection of such transforms over an AST, by the
way. Documentation generators are transforms over either an AST
(source-based doc generators) or a set of modules' contents (e.g. epydoc
Zope 3 transforms object trees into views. It also uses something called
"event adapters" that are basically a crude sort of before/after/around
method system. Twisted and Zope also do a lot of adaptation, which is sort
of a poor man's generic function combined with namespaces.
>Note that if any of these participants *do* have prior knowledge of the
>others, then the need for a generic adaption framework is considerably
>weakened. So for example, if (2) already knows all of the types of
>objects that are going to be operated on, then it can simply hard-code
>that knowledge into its own implementation.
One of the goals of PEP 3124, btw, is to encourage people to use overloads
even in the case where they *think* that they know all the types to be
operated on, because there is always the chance that somebody else will
come along and want to reuse that code. Pydoc and epydoc are good examples
of a situation where author #2 thought they knew all the things to be
>Similarly, if (1) knows that
>it is going to be operated on in this way, then it can simply add a
>method to do that operation. Its only when the system needs to be N-way
>extensible, where N is the number of participants, that a more general
>dispatch solution is required.
This makes it sound more complex than it is; all that is required is for
one person to try to use two other people's code -- neither of whom
anticipated the combination.
This situation is very easy to come by, but from your description each of
persons 1 through 4 might conclude that since they normally work alone,
this won't affect them. ;)
>OK that is the description of the use case. I'd be interested to know
>what uses cases people have that fall *outside* of the above.
Well, consider what other things generic functions are used for in ordinary
Python, like len(), iter(), sum(), all the operator.* functions, etc. Any
operation that might be performed on a variety of types is applicable.
Of course, these generic functions built in to Python use __special__
methods rather than having a registry; but this is an implementation
detail. They are simply generic functions that don't let you register
methods for built-in types (since they're immutable and you thus can't add
the __special__ methods).
So, generic functions that allow registration are just a generalization of
what we already have so that:
1. there are no namespace collisions between authors competing for reserved
2. dispatch can be on any number of arguments
3. any type can play in any function, even the type is built-in
Note that if it sounds like I'm saying that all functions are potentially
generic, it's because they are. Heck, they *already* are, in Python. It's
just that we don't have a uniform way of expressing them, as opposed to an
ad-hoc assortment of patterns.
More information about the Python-3000