Monday, 3 September 2007

Method Dispatch and Scheme

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.

2 comments:

Mana said...

How do you use such funky features and then go back to an every day language?

Can Scheme be an everyday language?

Giles said...

With great difficulty and deep pain... :)

But in answer to your question, I don't know yet. I'd have to use it more first. The lack of libraries is still looking a bit like a deal breaker. And the big counter-argument to these funky features is:

"You mean I have to build the foundation of the object system myself?"

So far, yes. Though, again, I need to look further to be sure about that.