Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting started with Julia Multiple Dispatch

Tags:

julia

Here's what looks to me the simplest imaginable example of multiple dispatch in Julia - it's the entire (8 line) contents of a file called adhoc.jl.

f = function(x::String)
    println("Called first version of f")
end
f = function(x::Float64)
    println("Called second version of f")
end
f("x")
f(1.0)

and yet when I run that (via include("Adhoc.jl")) julia complains:

ERROR: LoadError: MethodError: no method matching 
(::getfield(Main, Symbol("##17#18")))(::String)

With screenshot here

If I change that second instance of f to g things work, but that's no longer making use of multiple dispatch. How come I can't get to first base with multiple dispatch?

like image 846
Philip Swannell Avatar asked Sep 07 '18 13:09

Philip Swannell


People also ask

What does multiple dispatch mean in Julia?

Using all of a function's arguments to choose which method should be invoked, rather than just the first, is known as multiple dispatch.

Why is multiple dispatch good?

Multiple dispatch is a way that we can apply function calls as properties of types. In other words, we can redefine the same function over and over again, but just plan for different types to be passed through it in order to essentially recreate the method to handle a new type. Consider the following example.

How is multiple dispatch different from method overloading?

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.

What is a macro in Julia?

Macros change existing source code or generate entirely new code. They are not some kind of more powerful function that unlocks secret abilities of Julia, they are just a way to automatically write code that you could have written out by hand anyway.


1 Answers

This is the corrected version:

function f(x::String)
    println("Called first version of f")
end
function f(x::Float64)
    println("Called second version of f")
end
f("x")
f(1.0)

The problem with your code is that your original code created an anonymous function and assigned it to a variable f. And you did it twice, thus f pointed only at function(x::Float64).

You can see the problem with your original code by running it in Julia REPL:

julia> f = function(x::String)
           println("Called first version of f")
           end
#3 (generic function with 1 method)

julia> f = function(x::Float64)
           println("Called second version of f")
           end
#5 (generic function with 1 method)

julia> methods(f)
# 1 method for generic function "#5":
[1] (::getfield(Main, Symbol("##5#6")))(x::Float64) in Main at REPL[2]:2

and you see that f points at an anonymous function which has only one method.

Running my code (you need to restart Julia REPL as f variable name will be already taken and it cannot be reassigned):

julia> function f(x::String)
           println("Called first version of f")
           end
f (generic function with 1 method)

julia> function f(x::Float64)
           println("Called second version of f")
           end
f (generic function with 2 methods)

julia> f("x")
Called first version of f

julia> f(1.0)
Called second version of f

julia> methods(f)
# 2 methods for generic function "f":
[1] f(x::Float64) in Main at REPL[2]:2
[2] f(x::String) in Main at REPL[1]:2
like image 193
Bogumił Kamiński Avatar answered Sep 30 '22 15:09

Bogumił Kamiński