-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
Currently, defining some form of API like so:
abstract type Foo end
"""
bar(::Foo)
Implements `bar` for subtypes of `Foo`. Needs to be implemented to fulfill the interface expected of `Foo`.
"""
function bar end
always throws a MethodError
. From a user-perspective, it's hard to find out whether bar
was supposed to be implemented by a package they're using or not - it could very well just be a bug, since all MethodError
communicates is "There is no method matching this". Since this can bubble up from deep in some library, it'd be better for users to be able to say "I got this NotImplementedError
", which also makes it clear to package maintainers that they forgot to implement some method that is required of the interface they claim to implement.
This feature request/proposal is aimed at solving this issue, by giving package authors & Base an option to communicate to users "There is no fallback definition, since your type should implement this". This is done with a new error type, NotImplementedError
, which is defined like so:
struct NotImplementedError <: Exception
interface::String
func::String
end
function Base.showerror(io::IO, nie::NotImplementedError)
printstyled(io, "NotImplementedError: "; color=:red)
print(io, "The called method is part of a fallback definition for the `", nie.interface, "` Interface.\n",
"Please implement `", nie.func, "` for your type T.")
end
and used like so:
julia> abstract type Foo end
julia> bar(::Foo, ::Int) = throw(NotImplementedError("Foo", "bar(::T, ::Int)"))
julia> struct Baz <: Foo end
julia> bar(Baz(), 1)
ERROR: NotImplementedError: The called method is part of a fallback definition for the `Foo` Interface.
Please implement `bar(::T, ::Int)` for your type T.
Stacktrace:
[1] bar(::Baz, ::Int64)
@ Main ./REPL[4]:1
[2] top-level scope
@ REPL[6]:1
This allows the distinction between intended-to-be-extended API (bar(::Foo, ::Int)
) and this-is-supposed-to-error (any other signature on bar
, which throws a MethodError
).
To be discussed
The details of what exactly NotImplementedError
should contain, since this version with just two strings is IMO too bare-bones, as it requires discipline/good grasp of the intended API to be able to create the string directly.
Why is this needed?
This error and variations on it are widespread throughout the ecosystem and I think Base could benefit from having some fallback definitions like the one above as well, to give much more informative error messages when subtyping e.g. <: AbstractArray
or other abstract types in Base.