In object-oriented languages such as C++ and Java, virtual functions are dynamically dispatched based on the runtime type of the receiving object. But if such virtual functions have an argument that is itself based on a class hierarchy, there is no way to associate dynamic dispatch based on both the receiver and the argument. In other words, the call
obj.foo(arg)
will invoke the correct foo() based only on the runtime type of obj. The runtime type of arg is never considered.
In my Advanced C++ course, I discuss a programming technique that shows how we can use templates to simulate multiple dispatch in C++ (inspired by an article that appeared in C++ Report, 1998). Multimethods have been part of Lisp for a long time (a multimethod is a method that is selected based on the runtime types of two or more of its arguments).
Consider a hierarchy of space objects as shown in the following figure.
We want to model collision between various space objects, for example, between SpaceShip and Asteroid, Asteroid and Mars, etc. We want to associate default collision behaviour between objects and at the same time handle specific cases where appropriate. The following code fragment (I have tested it in Allegro Common Lisp) shows how this might be implemented.
In this example, I have defined a method to handle collision between two SpaceObjects in general, and between Asteroid and Planet, as a special case. You can see that Lisp correctly chooses the most specific method based on both the arguments at runtime.
Although I have discussed an example with two objects, this works with any number of arguments! The example code can be downloaded here.
Recent Comments