[MUD-Dev] SMAUG Code (was Personality Types)

Bruce Mitchener bruce at puremagic.com
Fri Aug 24 00:11:48 New Zealand Standard Time 2001

Miroslav Silovic wrote:

> The proper approach is multiple polymorphic dispatch (here
> demonstrated using TinyCLOS syntax, employed by Guile's GOOPS):
>   (define-generic look)
>   (define-method look (subject <Player>) (object <Described>)
>      ;; the default, since all other cases inherit from (Player, Described)
>      ;; pair.
>      )
>   (define-method look (subject <Player>) (object <Room>)
>      ... )
>   (define-method look (subject <Troll>) (object <Room>)
>      ... )
>   (define-method look (subject <Player>) (object <Thing>)
>      ... )
> etc.

A quick definition before starting in: dispatch is the process of
determining what method should be invoked and then invoking it.  In
some systems, this is done by the compiler, other systems do it at
runtime. At any rate, there are several styles of method dispatch,
ranging from single dispatch in traditional languages to multiple
dispatch in Dylan, CLOS, to pattern matching in ML, and predicate
dispatch in Cecil.  These are just different strategies for handling
the general problem of dispatch.  I've given URLs to papers on some
of these in previous posts.

Sometimes, it is hard for people to see why multiple dispatch as
shown in Miro's example is substantively different or superior to
the more traditional style that is expressable in C++/Java (as shown
in Alistair's code).  I know that I spent a long time disliking
multiple dispatch. :)

Quoting a bit from this paper on an implementation of multiple
dispatch in Perl,


--- begin quote ---

     It's possible to build "hand-crafted" multiply dispatched
     methods that look at the types of each of their arguments and
     react accordingly. For example, a normal (singly- dispatched)
     method could use ref or isa to determine the types of its other
     arguments and then select the correct behaviour in a cascaded
     if statement. Alternatively, it's possible to use hashes of
     hashes to set up a multidimensional table of subroutine
     references, then use the class names of the arguments (again
     found with ref) to index into it.  Both these approaches are
     described in detail in [1,2].

     The problem is that such hand-crafted mechanisms are
     complicated to construct and even harder to debug. And because
     every hand-built method is structurally similar, they're also
     tedious to code and maintain. Life would be very much easier if
     it were possible to define a set of identically named methods
     with distinct parameter lists, and then the program would
     "automagically" find the right one. Such a set of multiply
     dispatched methods is known as a multimethod, and each
     alternative method in the set is known as a variant.

---- end quote ----

One of the goals of using multiple dispatch rather than double
dispatch (like the pattern that Alistair used in his post) is that
it can simplify the longer term maintainence of your codebase, as
adding a new class to the system needn't mean that you have to go
and modify a bunch of methods.  Instead, you need only provide
variants that are specialized for the new class.  This is a very
powerful concept and can lead to radical simplifications in the
structure of code when employed properly.

With the more generalized form, predicate dispatching, that I've
previously mentioned on the list, its power grows.

And multiple and predicate dispatch can be applied outside the
domain of method lookup and dispatch.  Any problem where you are
taking a set of input values and considering what action to carry
out can benefit.  An example of this might be determine which event
handler to run for an event.  (Depending on the structure of your

 - Bruce

MUD-Dev mailing list
MUD-Dev at kanga.nu

More information about the MUD-Dev mailing list