multi-dispatch (was Re: large class hierarchies in python)

Alex Martelli aleax at aleax.it
Tue Sep 11 07:32:31 EDT 2001


"Justin Dubs" <jtdubs at eos.ncsu.edu> wrote in message
news:9nismr$fve$1 at uni00nw.unity.ncsu.edu...
    ...
> Now, I've only been looking at this language for a little bit now....
> but.... it seems to me that Multi-dispatching is just a fancy new word for
> polymorphism and more over is rather poorly implemented in Dylan.  Hell, I

A brief tirade in favour of multi-dispatching...:

It's runtime-polymorphism over an unlimited number of objects, rather
than over one object at a time.  In any language that doesn't offer
it (i.e., any I've ever used, except for Lisp and Dylan), one often
finds oneself working around it with kludges &c -- just like one has
to do for even single-object polymorphism in non-OO languages.

Take a typical case.  We have several kinds of objects (and more
kinds will be developed in the future) that need to render
themselves over several kinds of output-media (and more kinds
will be developed in the future).  Basically, the typical,
elementary first example of polymorphism where 'shapes' render
themselves onto a canvas -- except that, instead of a 'canvas'
with a single (abstract) interface, we have a variety of kinds
of output media that is just as wide and bewildering as the
variety of objects needing rendering (and the latter are not
limited to just 'shapes' -- there's many more kinds).

How do we approach this in Python, C++, or other single-dispatch
OO language?  Basically, we approach it with great difficulty,
through such kludges as the Visitor pattern, Martin's Acyclic
Visitor variation thereof, and other kinds of more or less
masqueraded *type-testing* (UGH!).  The least-inelegant approach
I know is based on Protocol Adaptation (PEP 246 -- which nobody
important seems to think is as crucial as it looks to me!-),
but it's still at heart a moderately-softened typetesting-like
kludge.  Basically, function render(renderable, outputmedium)
must have SOME "hard-wired" knowledge of possible varieties of
"kind of output interfaces" and try protocol-adaptation "in
parallel" over the renderable and outputmedium, from most desirable
match down to least desirable, until it finds a pair of protocols
(one to which the renderable can adapt, one to which the
outputmedium can adapt, and such that the two protocols match
each other) or, failing to find any match, gives up with some
appropriate exception about "there's no way this renderable can
render itself on this outputmedium".  I put "hard-wired" in
quotes because one can rely on some registry of protocols and
protocol-matching functions, dynamically or persistently
updated as new kinds of objects and media are introduced.  But
it still IS a kludge -- the language isn't supporting you in
any way, really... count yourself lucky if it isn't actively
_fighting_ you through static typing!-)

Multiple-dispatch languages put paid to all this.  "render"
becomes a generic function, and specific ways to render a
renderable object of a certain kind onto an output medium
of some kind become specific methods implementing that
generic function.  Whoever introduces new objects can add
the appropriate methods to render them onto known kinds of
output media -- and, vice versa, whoever introduces new
output media can add appropriate methods for known kinds of
objects to render themselves on those media.  The need to
decide whether such methods "belong" to the renderable
object, or to the output medium, is totally artificial, just
as, say, the need to establish object ownership for purposes
of deletion is artificial in C++ and due to the lack of
built-in garbage-collection functionality in the language.


This is exactly the kind of thing that makes it worthwhile
to learn new languages -- exploring what IS possible in
programming, as opposed to what some given _language_ makes
it appear possible:-).

And the Dylan implementation looks fine to me in as far
as I've dug into it.  What do you find wrong with it...?


> even prefer C++ over Dylan as far as polymorphism.  Plus I find the
overall
> syntax just clunky and unappealing.  The whole var :: <type> thing just
> doesn't do it for me.

I'm no fan of Dylan syntax, either.  But syntax sugar is
never a crucial determinant for me.

> I'm new to the optional static typing.  I'm familiar with the concept of
> dynamic and static typing and suppose I can see the advantage in optional
> static typing, but I'm very non-commital at this point.  I'll need to do
> some more reading and experimenting with it.

It goes hand in hand with Dylan's dispatching strategy,
by the way.  Any generic function is dispatched to some
specific method based on the most specific types that
the compiler is able to attribute to the objects that
are involved in the call -- the compiler can do some
type inference, but often you can help it by asserting
what you know to be true by design intent.

Your assertions can be used for error-checking (much
like 'assert' is in Python or C) but also, the compiler
can rely on them (whether it also doublechecks them,
or not) and compile efficient code for dispatching,
code that is based on types as precise as they can be.

A good runtime system can also take a trace of actual
types encountered at key points during a set of runs,
compare them with the types that could be determined
by compile-time type-inferencing alone, and SUGGEST
to you what type-annotations you could probably use
for better error-checking and/or better performance.

(I'm not sure if anything like this "good runtime" is
around for Dylan, but it's the kind of thing that you
were already able to find for _LISP_ over a decade
ago:-).

Type-issues don't exhaust programming one way or
another, mind you, and similar concepts (hints to
the compiler, expressing design intent, usable for
error checking AND for optimization) could well
also apply to issues that it would be very strained
to consider "type" issues.  But, hey, it's a start!-)


> > For completeness, I should mention Erlang -- it has a lot of
> > emphasis on distributed/concurrent programming, FP (single-
> > assignment), dynamic typing -- an interesting combination, and
> > I believe it's _the_ FP language on which most money is being
> > invested and made these days (both in Ericsson development,
> > and in other companies, such as one which was acquired by
> > Nortel about a year ago and whose name now escapes me).
>
> I checked out Erlang.  It looks interested.  I've got it bookmarked and
will
> do some more reading when I have some more time.  Thanks for the idea.

It definitely does look like a case of "and now for something
completely different" from the viewpoint of most other langs:-)


Alex






More information about the Python-list mailing list