I would like to name a function draw
in multiple modules. (My graph theory module would have a draw
from drawing graphs, my hyperbolic geometry module would have a draw
for drawing things in the hyperbolic plane, and so forth.) At times, I’d like to have a few modules loaded at the same time, but Julia tells me that the name is already taken. I thought, thanks to multiple dispatch, that as long as the argument types are different, this is possible. But I’m having trouble. Suggestions on how to achieve this please?
You need to extend the draw
method in the same way as you extend Base.getindex
for example (prefix with module name to the module that defined the actual function that the rest of the modules extend).
If all methods that happened to have the same name automatically got merged, that would be kinda chaos.
Two options: If you want them to be completely unrelated functions that happen to share the name draw
, just use the qualified names:
import A, B
A.draw()
B.draw()
On the other hand, if they are supposed to be part of a family of related functions, so that you can have functions from module C
that act on objects from A
or B
generically, e.g. a function foo(x) = (dosomething(x); draw(x))
that can act on an x
from A
or B
, then the modules have to know about one another. In this case, as @kristoffer.carlsson says above, you need to extend a common draw
function in A
and B
:
module A
using GenericDraw # first module where draw is defined
...
GenericDraw.draw(x::Atype) = ...
end
module B
using GenericDraw # first module where draw is defined
...
GenericDraw.draw(x::Btype) = ...
end
Then both A
and B
are defining different methods of the same draw
function, dispatched by types defined in those modules.
Thanks, but I’m not understanding. Could I have a Master
module that just defines:
function draw()
end
And then modules A
, B
, and so on with
import Master: draw
function draw(x::Atype) .... end
in module A
, and likewise in B
and C
. Or do I have no choice but to use A.draw(...)
and B.draw(...)
and so on.
I thought with multiple dispatch I could have lots and lots of functions named draw
so long as their arguments were different types.
Very helpful. I think I’ve got it. THANK YOU!
Yes, you could do that.
A generic function has some “higher level concept” that we extend with other types. For example, let’s look at the docstring for push!
help?> push!
search: push! pushfirst! push pushfirst pushdisplay
push!(collection, items...) -> collection
Insert one or more items at the end of collection.
If you extend Base.push!
then you opt into the “contract” that is specified by the function docstring. By doing so we can write generic code that works for many types of collections.
However, let’s say you are writing a game or something where you have a method called push!
which pushes another player. Then you should not extend Base.push!
because this function has a completely different meaning. There is no way to write generic code with Base.push!
and your game version of push!
.
So presumably, your draw
function in the “Master” module has some higher level concept of drawing associated with it. Then you extend that function using Master.draw
with other types that agree to that concept and we can write generic code using that draw
function.