4

I have seen some resources where it state that dynamic dispatch and the late binding are the same. If so then binding should be equal to dispatching. In some places they state overloading/early binding/ static dispatch as same and overriding/late binding/ dynamic dispatch as same.

So I came up with an analogy to understand this. Is the below analogy correct ? or how can I modify the below explanations.

We have a class structure as below.

class Board {
    public void show(){};
}

class Shape{
    public void draw(Board board) {};
}

class Square extends Shape {
    public void draw(Board board) {
        System.out.println("Drawing a Square");
    };
}

class Circle extends Shape {
    public void draw(Board board) {
        System.out.println("Drawing a Circle");
    };
}

We have :

Shape shape = createShape(type); // This will return any of Shape, Square, Circle
shape.draw(board);

We have :

Board myBoard = new Board();
myBoard.show();

And I came up with few explanations,

Binding : Deciding the actual type for the shape (can be Shape, Square or Circle). Given that if type of shape is known only at the run time it is late binding. Deciding type of myBoard can be done in compile time. Which is early binding

Dispatching : Deciding the actual implementation for draw is considered dispatching. Given that if the actual implementation of draw can only be decided at run time it is dynamic dispatching otherwise if it can be decided at compile time it is called static dispatching

Static Dispatch : Happens when I know at compile time which function body will be executed when I call a method. So myBoard.show(), here the method show can be statically dispatched. Where shape.draw(board) we can't dispatch draw statically since we can't guarantee which function body will be executed at runtime.

Single Dispatch (Dynamic) : An implementation for the draw will be chosen based only on shape's type, disregarding the type or value of board.

Multiple Dispatch (Dynamic) : The types of the shape and board together determine which draw operation will be performed. (In this case it is Double Dispatch)

Few resources I used :

Community
  • 1
  • 1
prime
  • 14,464
  • 14
  • 99
  • 131
  • 3
    "If so then `binding` should be equal to `dispatching`." - I wouldn't say that. "Binding" refers to associating an identifier to a method. "Dispatching" refers to making the actual call. But if you "bind late", there's no point in dispatching to a statically decided method. If you "bind early" you don't have a choice, you must select a method at compile time. – aioobe Mar 23 '18 at 15:24
  • So is late binding is actually dynamic dispatching ? What can you say about the above explanations, are the explanations correct then ? – prime Mar 23 '18 at 15:30
  • 2
    Sure, late binding can be seen as synonym to dynamic dispatch. (You can't really have one without the other.) Re. **Binding**: Not the actual type for `shape`, what _method_ to call which Java happens to do based on the type of `shape`. **Dispatching**: LGTM. **Static Dispatch**: Well, `Board.show` could be overridden. I'd agree if the method was static or if `Board` and/or `Board.show` was final. **Single Dispatch/Multiple Dispatch**: Well, could be argument type, could technically be some other attribute too, like type of `shape` + phase of the moon. – aioobe Mar 23 '18 at 16:22
  • So basically it to be static dispatch the method should be non-virtual ? – prime Mar 23 '18 at 16:31
  • @aioobe so the single and multiple explanations are correct but there can be other scenarios and combinations as well, this is what you meant I guess. – prime Mar 23 '18 at 16:33
  • Well, if the result of the method is statically decidable you can dispatch it statically. (I assume you've read the [wikipedia page](https://en.wikipedia.org/wiki/Static_dispatch).) – aioobe Mar 23 '18 at 18:48

1 Answers1

1

To finally give this question an answer:

Binding and dispatch are not the same.

  • Binding in general refers to resolving a symbol to some value/object/implementation. For example, an assignment statement x = 42 binds the symbol x to the value of the expression 42. Type names can always be resolved during compile time in Java.

  • Dispatch (or more precisely call dispatch or method dispatch) is the kind of binding that resolves a method call (or function call) to a method implementation. With static dispatch or early binding the target of that call can be known at compile time, with dynamic dispatch or late binding of method calls the target is selected at run time.

    Interface methods or virtual methods (the default in Java) use dynamic dispatch. Final methods, private methods, and static methods are effectively statically dispatched (though strictly speaking, the JVM still has to resolve the call).

I'll also quickly mention that the static type of an expression is the statically known or “declared” type of an expression, and that the dynamic type is the actual type of the runtime value of that expression. E.g. when we declare a variable Board b, then the static type of b is the Board class but the dynamic type might be Board or any of its subclasses – we don't know until it is assigned a particular object. A dynamically dispatched method can be bound as soon as the dynamic type is known (assuming type-based single dispatch as in Java).

Your myBoard.show() example uses a virtual method and would usually be dynamically dispatched: myBoard is declared to have type Board or any Board-subclass. This would change if you declare the class or show() as final. In practice, this particular example can be optimized to static dispatch because you construct the new Board() in the same scope, so the dynamic type of myBoard is known. But that is only an optimization.

In contrast, your createShape().draw() example clearly is dynamic dispatch, because the dynamic type of createShape() is not known by the caller.

Your understanding of single dispatch/multiple dispatch is essentially correct.

I'd like to point out that “dispatching” in its general sense of resolving a function call is not necessarily restricted to types. We could also dispatch a call using logic in if/elses. Consider this example where we dispatch a quadrant(x,y) call to a specific quadrant like north-east, depending on the values of x and y. This is static dispatch from the perspective of the language, but behaves more like static dispatch from the perspective of a programmer.

class Quadrants {
  ...
  public static void quadrant(int x, int y, String value) {
    // dispatch a call with a x→east, y→north coordinate system
    if (x >= 0) {
      if (y >= 0) {
        quadrantNE(value);
      } else {
        quadrantSE(value);
      }
    } else {
      if (y >= 0) {
        quadrantNW(value);
      } else {
        quadrantSW(value);
      }
    }
  }
  private static void quadrantNE(String value) { ... }
  private static void quadrantNW(String value) { ... }
  private static void quadrantSE(String value) { ... }
  private static void quadrantSW(String value) { ... }
}

Under the hood, a language runtime would also just use some logic to perform dynamic dispatch, especially for multi-dispatch. Type-based single dispatch (like instance method calls in Java where the static type is a class) can be implemented with a simple table lookup (vtable dispatch) and doesn't need complicated logic.

amon
  • 57,091
  • 2
  • 89
  • 149