[Python-3000] native support for multiple dispatch in 3.0 ?
Phillip J. Eby
pje at telecommunity.com
Thu Nov 16 19:23:30 CET 2006
At 12:44 PM 11/16/2006 +0100, Fredrik Lundh <fredrik at pythonware.com> wrote:
>since it seems to be impossible to bring up new ideas in subthreads, I
>though I'd give this one its own thread:
>
>- has there been any discussions on making RuleDispatch-type mechanisms
> available on a more fundamental level?
Only the discussion several months ago, where I tried to show that you
could treat all functions as extensible, by using extensible functions to
define them. (This makes it possible to keep optimizations like
tp_as_sequence->tp_len in place at the C level to support fast builtins.)
I was also trying to push for something like a 'defop' statement of the form:
defop expr(...):
...
Which, instead of binding the resulting function to 'expr', would invoke
something like:
addmethod(expr, func, containing_class_or_None)
Where addmethod is a builtin generic function that can be extended to
support user-defined generic function implementation. (Of course, this
proposal assumes type information of some kind is available in the function
signature, making simple implementations simple.)
One purpose of the proposal is to let us get rid of most __special__ names
syntactically, even though the implementation would retain them "under the
hood". Instead of 'def __iter__(self)', one would 'defop iter(self)',
'defop operator.add(self, other)', etc.
>could someone perhaps come up with a list of real-life uses for PJE's
>existing dispatcher implementation?
http://peak.telecommunity.com/DevCenter/SecurityRules is one; in fact it's
the major reason I wrote RuleDispatch in the first place. I know that
TurboGears is said to be doing something similar of their own. There are
also other people doing enterprisey things that they don't tell me much
about. People doing virtual world stuff or classic adventure games have
also expressed interest.
I myself have found that I don't use full predicate dispatch as often as I
use multiple or even single-dispatch generic functions. I even went so far
as to create this package so as to be able to use single-dispatch functions
in code I'm doing for Chandler:
http://cheeseshop.python.org/pypi/simplegeneric
And here's what I'm doing with it:
http://svn.osafoundation.org/chandler/trunk/chandler/parcels/osaf/sharing/EIM.txt
http://svn.osafoundation.org/chandler/trunk/chandler/parcels/osaf/sharing/eim.py
The place I'm mostly using multiple dispatch, however, is in the work I'm
doing on RuleDispatch's better-documented and better-tested replacement-to-be:
http://svn.eby-sarna.com/PEAK-Rules/
The new package uses an enhanced version of Guido's type-tuple dispatching
to do multiple dispatch, and I'm using that to bootstrap the more advanced
features.
For more "real world" usage, however, note that adaptation is a subset of
single-dispatch generic functions, so everything in Zope and Twisted that
uses adapters would qualify. Zope 3 also does what they call "tuple
adapters" which is basically a rather twisted way of implementing multiple
dispatch generic functions without actually having a function. :) They
also have event adapters that are a lot like the method combination
features of RuleDispatch and PEAK-Rules.
(And of course, for further single-dispatch use cases, one need look no
further than the builtin polymorphics and stdlib stuff like pickle and pprint.)
>or should we go all the way: how about using this mechanism for *all*
>dispatching, even the usual dispatch-on-instance handler? and poly-
>morphic builtins too, while we're at it?
I wouldn't go that far. I think we should keep most of the existing
C-level dispatch machinery: slots are fast. Instead, I think we should
just have One Obvious Way to *add methods* togeneric functions, regardless
of how they are implemented. If there is a builtin 'addmethod()' generic,
then it can be defined to do the right thing for builtin slot-based
generics. And if you implement your own specialty generics (ala
RuleDispatch), you would simply:
addmethod(addmethod, addmethod_for_my_new_type, my_new_type)
Or more succinctly:
class my_new_type:
...
defop addmethod(self, func, cls=None):
# code to add a method to this generic function object
Actually, it would be nice if you could subclass 'function', just so that
we could have 'inspect' and 'pydoc' functions treat your instances
sanely. All of my generic functions go to insane lengths to *be* normal
function objects so that inspection and documentation tools will treat them
sanely. OTOH, I suppose if the inspect and pydoc code were refactored to
generics, that wouldn't be a problem, because you could just 'defop
inspect.getdoc(...)' or whatever...
More information about the Python-3000
mailing list