Multiple dispatch example at/for julialang.org

I think I understand multiple dispatch, but the example there is seemingly only single dispatch. People already think multiple dispatch is just the same as overloading, so which example might show it off better, and is actually multiple, as in 2+, not just one dispatch?

What kind of code might we want to show off there? I really like the syntax for e.g. polynomials.

f(x) = 2x^2 + 1

but even such simple code might put of users as too technical. I would like an example anyone can understand, general purpose, not technical computing or too mathematical. Though maybe with unitful, using the same juxtaposition trick.

[The example shown returns a set tuple, peopke not knowing might misunderstand multiple dispatch, it’s great you have tuples (or sets), and can return multiple values…]

3 Likes

Are you referring to the “greet” example on the front page of julialang.org? That one returns a tuple, not a set. (Having the two invocations of greet on separate lines might nevertheless be easier to understand.)

2 Likes
function bong(x)
    return x^3
end
ulia> bong(3)
27

julia> bong("bing")
"bingbingbing"

Because bong is ducktyped, it will apply the ^ operator either to an integer or a string.

Isn’t overloading resolved at compile time and multiple dispatch at runtime?

Wikipedia uses this example.

abstract type SpaceObject end

struct Asteroid <: SpaceObject
    size::Int    
end
struct Spaceship <: SpaceObject
    size::Int                  
end

collide_with(::Asteroid, ::Spaceship) = "a/s"
collide_with(::Spaceship, ::Asteroid) = "s/a"
collide_with(::Spaceship, ::Spaceship) = "s/s"
collide_with(::Asteroid, ::Asteroid) = "a/a"

collide(x::SpaceObject, y::SpaceObject) = (x.size > 100 && y.size > 100) ? "Big boom!" : collide_with(x, y)
julia> collide(Asteroid(101), Spaceship(300))
"Big boom!"

julia> collide(Asteroid(10), Spaceship(10))
"a/s"

julia> collide(Spaceship(101), Spaceship(10))
"s/s"

Note quite. You are correct that overloading requires static knowledge of types. However multiple dispatch only describes the way method resolution works and does not specify whether this happens ‘at runtime’ or ‘at compile time’.
In Julia specifically, usually only the semantics are specified and the what gets compiled away or not is mostly an implementation detail. Fortunately the compiler is rather smart and manages to do most dispatch at compile time if one writes reasonable code :slight_smile:

Sometimes people refer to multiple dispatch that can be inferred statically, i.e. at compile time, as ‘static dispatch’. Conversely, if dispatch happens at runtime it is sometimes called ‘dynamic dispatch’. These terms are related to but somewhat different from ‘multiple dispatch’.

1 Like

Unfortunately, people get the wrong impression of multiple dispatch (or rather as implemented in Julia) from the Wikipedia entry and everything that parrots it:

Multiple dispatch or multimethods is a feature of some programming languages in which a function or method can be dynamically dispatched based on the run-time (dynamic) type or, in the more general case, some other attribute of more than one of its arguments.[1] This is a generalization of single-dispatch polymorphism where a function or method call is dynamically dispatched based on the derived type of the object on which the method has been called.

On the other hand, if you follow that primary source link, the linked introduction provides a fitting definition that doesn’t assert runtime types need runtime dispatch. I couldn’t figure out how to copy text from Google Books so here’s a screenshot:

Considering that devirtualization statically dispatches calls over runtime types for single-dispatch languages, it’s not hard to imagine this happening for multiple dispatch. But it’s not natural to think of that when just looking up definitions, and when people have, they often think it doesn’t count as multiple dispatch anymore. Even a little misinformation can cause a lot of headaches.

1 Like

After reading Julia: A New Approach to Numerical Computing, I get the impression that the creators of Julia meant multiple dispatch for dynamic multiple dispatch.

Multiple dispatch is the selection of a function implementation based on the types of each argument of the function.

We have not seen this in the literature but it seems worthwhile to point out four possibilities:

  1. Static single dispatch (not done)
  2. Static multiple dispatch (frequent in static languages, e.g. C++ overloading)
  3. Dynamic single dispatch (Matlab’s object oriented system might fall in this category though
    it has its own special characteristics)
  4. Dynamic multiple dispatch (usually just called multiple dispatch).

Class-based object oriented programming could reasonably be called dynamic single dispatch, and overloading could reasonably be called static multiple dispatch. Julia’s dynamic multiple dispatch approach is more flexible and adaptable while still retaining powerful performance capabilities

“Dynamic multiple dispatch” in that paper means dispatch over multiple dynamic types, not that the dispatch itself must be dynamic, which was never true even for “dynamic single dispatch.” We don’t use those terms in practice because it’s ambiguous what’s actually dynamic.

2 Likes

I think this @trace_dispatch can help in finding the methods that were compiled via dynamic dispatch. :child: How to use it?