The Wikipedia page on multiple dispatch has a complete exsmple in C#, but then in Julia the same exanple is given only as a sketch… could someone that inferstand C# complete the Julia example ? it would then be nice to compare the two implementations…
What are you missing from the example? return "a/s"
instead of the comment?
It really is that short.
Since it’s not that long:
abstract type SpaceObject end
struct Asteroid <: SpaceObject
size::Int
end
struct Spaceship <: SpaceObject
size::Int
end
collide_with(x::Asteroid, y::Asteroid) = "a/a"
collide_with(x::Asteroid, y::Spaceship) = "a/s"
collide_with(x::Spaceship, y::Asteroid) = "s/a"
collide_with(x::Spaceship, y::Spaceship) = "s/s"
collide(x::SpaceObject, y::SpaceObject) = x.size > 100 && y.size > 100 ? "Big Boom!" : collide_with(x,y)
It was more than the whole program, but I think I now got the logic of the C# implementation…
The problem with these sort of short examples is that they’re only using regular method overloading since we’re in a single namespace. Multiple dispatch really only begins to come in handy when you can define a new method with new types for a function of a different namespace, that didn’t originally knew about these types.
E.g. the examples from this juliacon talk are much better in my opinion - they show how bringing together multiple different namespaces (that don’t inherently know about each other) can work because of multiple dispatch:
Would it be correct to say that the advantage derives from the fact that high level functions can delegate specialisation to lower level ones? So if the lower-level methods are implemented for the new type, the high level methods would be also fine with it… ?
No, that’s just a sideeffect due to how the C# example has to be structured because of the way everything has to be inside of a class in C#.
E.g. I could extend the collide
function like so:
collide(a::Asteroid, b::SpaceObject) = a.size >= 1_000_000_000 ? "Extinction event, have a nice day!" : collide_with(a, b)
and the other implementation on two ::SpaceObject
s wouldn’t care:
julia> collide(Asteroid(1), Spaceship(1))
"a/s"
julia> collide(Asteroid(1_000_000_000), Spaceship(1))
"Extinction event, have a nice day!"
julia> collide(Spaceship(1_000_000_000), Asteroid(1))
"s/a"
the first two calls call the new method since the first argument is an Asteroid
. Before defining that new specialized method collide(::Asteroid, ::SpaceObject)
, we would have gotten "a/s"
for either call because only one of the two space objects has a size greater than 100
.
–
That said, since every function in julia has multiple dispatch, this works on all levels - high level API as well as low level workhorse functions.