I'm gonna explain my problem on a minimal example. Let's say I have three files:
A.jl
module A
export Atype, f
type Atype
end
f = function(x::Atype)
println("f called with A")
end
end #module
B.jl
module B
export Btype, f
type Btype
end
f = function(x::Btype)
println("f called with B")
end
end #module
Main.jl
using A
using B
main = function()
x = Atype()
f(x)
end
main()
Here I have two versions of f
function. If I understand the idea of the multiple dispatch correctly, it should be deducted during runtime which version should be used. Hence, I expected that running Main.jl would print f called with A
. Unfortunately, I get
$ julia Main.jl
ERROR: type: anonymous: in typeassert, expected Btype, got Atype
in include at /usr/bin/../lib64/julia/sys.so
in process_options at /usr/bin/../lib64/julia/sys.so
in _start at /usr/bin/../lib64/julia/sys.so
while loading /home/grzes/julia_sucks/Main.jl, in expression starting on line 9
If I comment out using B
, it works fine. Clearly, f
from B.jl overwrote f
from A.jl.
So, the question is: where does the problem lie? In my approach or in the version of Julia I use (0.3.7)? How can I circumvent this?
Note that replacing using A
with import A
and using fully qualified names (e.g. A.f
) is not a good solution. It contradicts with the crux of multiple dispatch -- at compile time I don't know if I should use A.f
or B.f
.
You have to make A.f
and B.f
the same function (in the example above they are just different functions with the same name). Then you can overload one method in each of the modules and multiple dispatch will do its job.
The way to achieve this is either to have one of the modules import the function f
from the other (eg import A.f
in B
) before extending it with a new method, or adding a third module C
with an f
function that both A
and B
import (you can use a dummy signature like f(::Union()) = nothing
that never applies to create a function without adding any real method). Our extend the function from the other module directly, as in
function A.f(x::Atype)
println("f called with A")
end
This will make Julia understand that the two f
refer to the same concept, and they will actually be the same object in both modules. Adding a method modifies the generic function object, so this change will be visible everywhere that f
is used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With