[MUD-Dev] SMAUG Code (was Personality Types)
Bruce Mitchener
bruce at puremagic.com
Fri Aug 24 00:11:48 CEST 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,
http://www.csse.monash.edu.au/~damian/TPC/1999/MultipleDispatch/Paper.html:
--- 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
system.)
- Bruce
_______________________________________________
MUD-Dev mailing list
MUD-Dev at kanga.nu
https://www.kanga.nu/lists/listinfo/mud-dev
More information about the mud-dev-archive
mailing list