Quantcast
Channel: Abhijit Nadgouda @ iface » programming
Viewing all articles
Browse latest Browse all 35

Single, Double And Multiple Dispatch

$
0
0

This post has already been published on code::gallery blog which now has been merged into this blog.

These are mechanisms in object oriented programming languages to identify the funciton/method to be invoked. The dispatch in the nomenclature is about dispatching messages to objects, as it is said in Smalltalk. It is equivalent of saying invoking methods of an object.

Single Dispatch

Typically, multiple methods or functions are given the same name, because the represent the same purpose. In the single dispatch mechanism, the method to be invoked in determined using the object, usually type of the object, on which it is invoked. It also includes the parameters, but the parameter types are identified at the compile time whereas dynamic binding or dynamic dispatch can be used for object on which method is invoked. This object is also syntatically highlighed, like obj.behave(the, arguments).

Most of the conventional and popular languages, like C++, Java or Smallatalk inherently support single dispatch mechanism.

Double Dispatch

Why is anything more than single dispatch is being considered? Because in the real world it is required. In the real world, the behavior between two objects is not dependent on both of them and not just one. Lets consider an example.

Your behavior would change when you face other humans, the domestic cat or the tiger. This means that your actions are dependent not only on you but also on whom you face. This cannot be incorporated using the single dispatch mechanism.

So we come up with double dispatch. It is in fact a simulation using the single dispatch mechanism, and hence is not completely extensible. Consider the following example code:

class Human;
class Cat;

class Animal
{
    public:
        virtual void face (Animal& animal);
        virtual void face (Human& human);
        virtual void face (Cat& cat);
}

class Human : public Animal
{
        virtual void face (Animal& animal)
        {
            animal.face(*this);
        }

        virtual void face (Human& human);
        {
            // shakehand
        }

        virtual void face (Cat& cat);
        {
            cat.face(*this);
        }
}

class Cat : public Animal
{
        virtual void face (Animal& animal)
        {
            animal.face(*this);
        }

        virtual void face (Human& human);
        {
            human.face(*this);
        }

        virtual void face (Cat& cat);
        {
            // run
        }
}

This code works. What is done here is that two calls are used to identify both the types involved. Consider this code:

Animal& acat = Cat();
Animal& ahuman = Human();
ahuman.face(acat);

Here, when ahuman.face(acat) is invoked, it in turn invokes Cat::face(Human&) at which point both the types are determined. This is the double dispatch mechanism.

However, as you can see, the biggest disadvantage is that the base class Animal has to know all the derived classes. Everytime a new animal is added, the interface of Animal has to change making it impractical, exactly what the Dependency Inverstion Principle advises us to avoid.

Multiple Dispatch

So we need multi dispatch, also called multimethods. The multidispatch mechanism considers all parameters equally and hence can provide easier and more extensible implementations. Some of the languages that support multiple dispatch are Common Lisp, Dylan, Nice, Scheme and Slate.

One of the common designs of multiple dispatch is to separate the methods from the class (which contains the structure). This allows for treating all the parameters equally.

Some of the conventional languages also support multimethods through extensions – Multimethods for Python, Multimethods for Perl, MultiJava, Ruby, C++ with Multimethods.

More reading:

Technorati tags: , , ,

Copyright Abhijit Nadgouda.



Viewing all articles
Browse latest Browse all 35

Latest Images

Trending Articles





Latest Images