# Throwing my own \`NotImplementedError\` to emulate abstract methods

**URL:** https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680
**Category:** General Usage
**Created:** [April 19, 2023, 9:27pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680 "2023-04-19T21:27:54Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![zuckerruebe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zuckerruebe/32/49121_2.png) [@zuckerruebe](https://discourse.julialang.org/u/zuckerruebe)
#### Post date: [April 19, 2023, 9:27pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/1 "2023-04-19T21:27:55Z")

</div>

Hi there

I want to write a piece of software that my users can extend by writing “plugins” for it. Specifically, they would provide their own types in their plugins, that the main program will then operate on. For the main program to be able to do that the provided types need to adhere to a well defined interface. I think that’s a setting many of us have encountered before.

In a language like, say, Python an abstract base class that people can inherit from would probably be the most common way to go about that. Now, in Julia, in order to at least document what that interface is I’m tempted to write

```julia
computeOutputsAfter(unit::Unit, timestep::TimestepInH, inputs::Inputs) = throw NotImplementedError() # returns Outputs
setInputs!(unit::Unit, inputs::Inputs) = throw NotImplementedError() # returns Nothing

```

where `Unit` is the base type the plugin types extend, the two functions are the ones that need to be defined on each plugin type and `NotImplementedError` I’d defined myself in analogy to Python. Unfortunately, the expected return type can only be given as a comment AFAIK. Anyway, I find the above preferable over

```julia
function computeOutputsAfter end
function setInputs! end

```

– which I’ve seen mentioned in the documentation – because there I don’t even see the required number of arguments, let alone their type.

My question is: does that look like a reasonable approach or are there more common/idiomatic ways to do this in Julia.

Cheers,  
Damian

---

<div class="post-metadata">

### Author: ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)
#### Post date: [April 19, 2023, 9:34pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/2 "2023-04-19T21:34:07Z")

</div>

I would say don’t define the methods for the base (“abstract”) type. That way Julia will throw an error when a given plugin does not satisfy the required interface.

Make sure to document what interface is expected though.

---

<div class="post-metadata">

### Author: ![aramirezreyes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aramirezreyes/32/42573_2.png) [@aramirezreyes](https://discourse.julialang.org/u/aramirezreyes)
#### Post date: [April 19, 2023, 9:47pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/3 "2023-04-19T21:47:21Z")

</div>

This reminds me that such an implementation is considered and anti-pattern in [JuliaLang Antipatterns](https://www.oxinabox.net/2020/04/19/Julia-Antipatterns.html#notimplemented-exceptions) .

Of course, one could say that it is a matter of taste, but coming from such an experienced julia programmer it may be worth to take it into account.

---

<div class="post-metadata">

### Author: ![olynch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olynch/32/17839_2.png) [@olynch](https://discourse.julialang.org/u/olynch)
#### Post date: [April 19, 2023, 9:48pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/4 "2023-04-19T21:48:22Z")

</div>

The thing that has bitten me over and over with this is that when you define the method generically with a `NotImplementedError`, you can end up confusing dispatch if you want to, say, overload the method with something more specific for `unit` but more general for `intputs`. Then Julia will say that it doesn’t know which method to use.

So I’ve just learned the hard way to just do

```julia
function computeOutputsAfter end

```

with a comment for the type signature.

Julia has such a great type system that you want to use it as much as possible. But really, the type system is not a module system or a correctness system; it’s a dispatch and performance system. Having those methods defined to throw `NotImplementedError` doesn’t help with dispatch and doesn’t help with performance, and so isn’t really an idiomatic usage of the type system.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [April 20, 2023, 6:14am UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/5 "2023-04-20T06:14:59Z")

</div>

I find the following blog post to be the most relevant and interesting resource for issues related to the need for interfaces in real-world applications:

> **[Development with Interface Packages](https://invenia.github.io/blog/2020/11/06/interfacetesting/)**
>
> Over the last two years, our Julia codebase has grown in size and complexity, and is now the centerpiece of both our operations and research. This implies that we need to routinely replace parts of the system like puzzle pieces, and carefully test if...

---

<div class="post-metadata">

### Author: ![zuckerruebe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zuckerruebe/32/49121_2.png) [@zuckerruebe](https://discourse.julialang.org/u/zuckerruebe)
#### Post date: [October 1, 2024, 2:44pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/6 "2024-10-01T14:44:01Z")

</div>

That’s a good explanation, thanks! Where would that bare-bones “implementation” implementation typicall be put? In something like `unit_base.jl`?

Actually, could anyone point me to a project where something like is done, ideally to the documentation explaining what the expected signature is?

In reply to my own post, @aramirezreyes, already provided such an example here: [JuliaLang Antipatterns](https://www.oxinabox.net/2020/04/19/Julia-Antipatterns.html#notimplemented-exceptions)

---

<div class="post-metadata">

### Author: ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)
#### Post date: [October 1, 2024, 3:39pm UTC](https://discourse.julialang.org/t/throwing-my-own-notimplementederror-to-emulate-abstract-methods/97680/7 "2024-10-01T15:39:11Z")

</div>

At its core, a `MethodError` _only_ says “there is no method matching these arguments”; it doesn’t communicate whether there _should_ be such a method or not. This is why I disagree with the idea of just leaving the base function completely unimplemented. You don’t want to end up in a situation where a user implements your interface wrongly and tries to “fix” that by chasing `MethodError`s.

> [@zuckerruebe](#):
>
> Actually, could anyone point me to a project where something like is done, ideally to the documentation explaining what the expected signature is?

I’m the maintainer of [RequiredInterfaces.jl](https://seelengrab.github.io/RequiredInterfaces.jl/dev/index.html), which does exactly that. I use this package for pretty much all of my projects, where I want to provide a user-extensible API.

See also this github issue for more discussion about `NotImplementedError`:

> <https://github.com/JuliaLang/julia/issues/50196>
>
> Currently, defining some form of API like so:
> 
> \`\`\`julia
> 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:
> 
> \`\`\`julia
> 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
> 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
> \`\`\`
> 
> !\[image\](https://github.com/JuliaLang/julia/assets/11753998/e7a02901-95e2-44e7-9ba1-13b18b812d10)
> 
> 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\](https://juliahub.com/ui/Search?q=struct%20.%2aImplemented.%2aError&type=code&r=true) 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.

From my POV, this should just be part of Base.
