Method Dispatch and Scheme

gga

As I work
on Shrew
and attempt to learn more
about Scheme,
I’ve been doing some reading. And in one of my books I had one of
those ‘Aha!’ moments where I really saw the benefit in the Scheme way
of doing things.

In object-oriented languages there are two approaches to dispatching
methods.

Message
Passing: Objects are regarded as actors. Method call is
treated as sending messages to those actors. Method dispatch is
therefore determined solely based upon the type of the receiver of the
method, the types of any arguments is immaterial. SmallTalk typifies
this style. C++, Java and most other OO languages have adopted this
style (badly.) This is also known as single-dispatch.

Multi-methods:
Methods and the objects to which they can be applied are regarded as a
cartesian product: objects don’t own methods and methods don’t own
objects. Method dispatch is therefore determined from the type of all
the arguments
equally. CLOS uses
this style. I am not aware of any other widely used languages that
also use multi-methods.

The book I am currently reading laid out some Scheme code that showed
how to implement multi-methods, and then followed it up with some code
that implemented message passing. In both cases the code was extremely
simple and easy to understand: the basics for two object-oriented
approaches were right there on the page.

And most interestingly, there was no reason why both systems couldn’t
be used on different objects in the same program.

The book is about general computer science concepts, so it doesn’t
actually point out what it has just described, and nor does it provide
a complete implementation of an object system
(yet…) however it is interesting to see such a
fundamental part of a object system in so few lines of code. It is the
nature of Scheme that makes it possible to implement things that other
languages regard as ‘part of the language’ in your own programs.

It is not possible to do this in Java; it is not possible in C++, not
even
with template
meta-programming; and it isn’t even in possible in
Haskell*.

Now, that’s not to say that having both multi-method and message
passing dispatch is itself such a killer feature. But it’s going to be
kind of hard to beat a language to which both of these things can be
added so simply.

* Of course, via
differing mechanisms of varying degrees of pain, something like
multi-methods could be added to all of these languages. Here I am
talking about a simple, transparent at both caller and callee
technique for achieving multi-methods and message passing.