Multiple dispatch again
David Mertz
mertz at gnosis.cx
Thu Jan 2 02:01:42 EST 2003
I've got to thinking about multimethods/multiple dispatch lately. I
wonder if Pythonistas have some futher opinions on the use of these.
Actually, part of it is that I'd -really- like to better understand use
cases for multiple dispatch. As a trick, I can see it has a certain
elegance, but little rock/paper/scissors toys are not, finally,
compelling.
An inspiration for the code I am about to mention is simple and
beautiful code posted a bit over a month ago by Tim Hochberg. I played
with that, and enhanced it fairly greatly at:
http://www.gnosis.cx/secret/multimethods.py
I welcome comments of any sort on the code.
There are a few things that I had particularly in mind. In reading
about Dylan, I found that it has a method named 'next-method( )' to
propogate dispatch from the closest match to more distant ones. You can
control whether you want this to happen by including that method, or
not. Take a look at:
http://www.tpk.net/~ekidd/dylan/multiple-dispatch.html
In my code, I added the facility to propogate dispatch. Using the
simple example that was a topic of conversation here 6 weeks ago, you
can make a call like:
beats.add_rule((Fire,Thing), firepower, next_meth=AT_END)
I give you options to propogate dispatch either before or after the code
within the current method execution.
As well, I decided to make dispatch resolution order configurable.
Hochberg's example was perhaps naive in fixing resolution order
according to definition order. That seems a little fussier than I would
want. So I made that configurable as well, and provide four sample
resolution functions. Two are naively definition-order based (either
forward or reversed). But two others are perhaps better candidates:
'lexicographic_mro()' and 'weighted_mro()'. If I understand correctly
(which I may not), the first follows Dylan, the second follows Damian
Conway' Class::Multimethods. I would be interested to understand other
examples, particularly CLOS. I have little intuition about what is the
"right" answer.
Since I allow propogated dispatch, I had to decide what to do with
results from the function calls. I decided to accumulate all returned
values into a list, and let the user pick what they want. So for
example:
<fire, fire> ['Fire always wins!', 'Fire always wins!', 0]
But for a non-propogating rule, the list has a single member:
<rock, scissors> [1]
If you stick to either 'SKIP' or 'AT_END' propogation, you can count on
index 0 of the return being the most specific function's value. Or if
conversely, you like 'AT_START', you can use index -1. If you mix the
two styles, it could become complicated to find relevant return values.
Yours, David...
--
Keeping medicines from the bloodstreams of the sick; food from the bellies
of the hungry; books from the hands of the uneducated; technology from the
underdeveloped; and putting advocates of freedom in prisons. Intellectual
property is to the 21st century what the slave trade was to the 16th.
More information about the Python-list
mailing list