Currently, MethodErrors for missing methods do not print any information about the module to which the underlying function belongs. For example:
julia> module Bar
f(x::Int) = 10
end
Bar
julia> using .Bar: f
julia> f(10)
10
julia> f("hello")
ERROR: MethodError: no method matching f(::String)
Closest candidates are:
f(::Int64) at REPL[1]:2
This can make it more difficult to determine exactly which function I should overload to fix the method error. Just looking at the error message, it would appear that defining f(::String)
would be appropriate, but I actually need to define Foo.f(::String)
or import Foo: f; f(::String) = ...
.
The issue gets worse when method errors occur deeper in the code, as it can be pretty unclear what the originating module for a given function is.
To be clear, I’m not suggesting changing the language semantics at all, just the way we report errors.
I suspect that this would also help with a very common category of error for new users, which is failing to import Base
methods. For example, a new user might do the following:
julia> module Foo
struct Bar; end
sort([Bar(), Bar()])
end
ERROR: MethodError: no method matching isless(::Foo.Bar, ::Foo.Bar)
Given that error message, the natural thing to do is to define precisely what is suggested:
julia> module Foo
struct Bar; end
isless(::Bar, ::Bar) = true
sort([Bar(), Bar()])
end
WARNING: replacing module Foo
ERROR: MethodError: no method matching isless(::Foo.Bar, ::Foo.Bar)
but of course that doesn’t actually work.
If, instead, the MethodError printed MethodError: no method matching Base.isless(::Foo.Bar, ::Foo.Bar)
, then we would at least be helping users towards the correct implementation:
julia> module Foo
struct Bar; end
Base.isless(::Bar, ::Bar) = true
sort([Bar(), Bar()])
end
WARNING: replacing module Foo
Foo
Method ambiguity errors already show the function with its relevant module, so this is clearly possible. I’m happy to open a PR if this seems like a good idea.