Multiple dispach method overwritten


#1

Hi, I don’t understand why I’m getting this warning.

WARNING: Method definition grdtrack() in module GMT at c:\j\.julia\v0.6\GMT\src\grdtrack.jl:51 overwritten at c:\j\.julia\v0.6\GMT\src\grdtrack.jl:150.
WARNING: Method definition #grdtrack(Array{Any, 1}, typeof(GMT.grdtrack)) in module GMT overwritten.

The lines in question from this file, read

# ---------------------------------------------------------------------------------------------------
function grdtrack(cmd0::String="", arg1=[], arg2=[]; data=[], kwargs...)
...
end
grdtrack(arg1=[], arg2=[], cmd0::String=""; data=[], kw...) = grdtrack(cmd0, arg1, arg2; data=data, kw...)

The type of the positional arguments is not the same, so why does it say it’s the same method?


#2

Both methods have defaults for all positional arguments, so if you call grdtrack(), which method should be invoked?


#3

You mean without any argument as in?

grdtrack()

Well, for my case it doesn’t matter because without arguments the call is interpreted as a request to print a on line help and quit (which it does correctly)


#4

What I mean is that the ambiguity is for the method with no arguments, grdtrack().
It could match the definition at line 51 or the definition at line 150.

From https://docs.julialang.org/en/stable/manual/functions/#Optional-Arguments-1

“Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see Note on Optional and keyword Arguments).”


#5

Thanks, I understand now what you mean. But what is the difference to this case? Here I also can call foo() and no ambiguity is reported.

julia> foo(a::String="", b=[]; v=false, c=[], kw...) = 1
foo (generic function with 3 methods)

julia> foo(a=[], b::String=""; v=false, c=[], kw...) = foo(b, a; v=false, c=[], kw...)
foo (generic function with 5 methods)

#6

How is the language supposed to know that it doesn’t matter to you?


#7

I think at the REPL for Main module only, the first no-argument foo method is overwritten silently.
But if you wrap into a module, then you’ll get the method overwritten warning:

module Test
    foo(a::String="", b=[]; v=false, c=[], kw...) = 1
    foo(a=[], b::String=""; v=false, c=[], kw...) = foo(b, a; v=false, c=[], kw...)
end

Also I think method redefinition warnings might change in v0.7:

https://github.com/JuliaLang/julia/pull/23030#issuecomment-321612882

https://github.com/JuliaLang/julia/pull/23002

Also note that you’ll still have the conflict and overwritten method, just no warning.


#8

Ok, thanks, that explains completely what is going on. But I’m confused with the issues. #23030 is closed and #23002 was merged but I still get the same warnings with v0.7


#9

Only when precompiling?


#10

Only when precompiling?

Yes.
Is it the expected behavior?


#11

Yes.


#12

OK, and thanks for pushing this.