[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 
and pydoc).

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 
operated on.

>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 
method names
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 mailing list