What is the difference between multiple dispatch and method overloading?

In languages like Scala, one can have multiple definitions for one method name by changing the number of parameters and/or the type of the parameters of the method. This is called method overloading.

How is that different from multiple dispatch?

Thank you


Method overloading is resolved at compile time.

Multiple dispatch is resolved at runtime.

When using double dispatch the called method depends on the actual type of receiver and arguments. Method overloading however, only allows the called method to depend on the declared type of the parameters. Why? Java binds method calls at compile time with their full signature (early binding). The full signature includes all parameter types, hence when the actual type of an argument differs at runtime (polymoprhism), overloading does not work as you might expect!

void add(Foo o) { ... }
void add(Bar o) { ... }
void client() {
    Foo o = new Bar();
    add(o); // calls add(Foo) not add(Bar)!
}

using multiple dispatch however

void add(Foo o) { o.dispatch(this); }
void add(Bar o) { o.dispatch(this); }
void client() {
    Foo o = new Bar();
    add(o); // calls #dispatch as defined in Bar!
}

Things might slightly differ in Scala, though the general distinction should be the same as presented here in all programming languages.