Design pattern for correctly overwriting abstract methods (interface methods)

I have something like the following situation:

module Cache

export cache

function cache(data)
  throw(NotImplementedException())
end

end
module FileCache

import Cache

function Cache.cache(data)
  # do cache stuff
end

end
include("Cache.jl")
include("FileCache.jl")

# use caching

However, Julia complains that FileCache.cache overwrites Cache.cache and breaks pre-compilation. Having different method signatures fixes the problem, but I don’t want to invent artificial function signatures for interface methods just for this purpose.

What’s the correct way to do it?

1 Like

Going through some code I’ve seen from other authors, I think the solution is to pass a type for dispatching and specializing methods, ie:

module Cache

function cache()
  throw(NotImplementedException())
end

end
module FileCache

function cache(::Cache{FileCache}, data)
  # stuff
end

end

Is this the (only) way?

You can define a function with no methods:

function cache end

in the Cache module.

12 Likes

Ah, that’s brilliant, thanks!

An aside, after working with a lot of code that onces used this kind of NotImplementedException,
we concluded it was an antipattern.
and replaced it with declaring the functin in the

function cache end

form.

  • Plus a docstring saying what the espected signature was.
  • Plus a test-suite function which accepts an implementation of the interface in the docstring and tests that it follows the interface.

Its great.
Strong recommend,.

12 Likes

Excellent! It felt too much like Java anyway!

2 Likes

the really big downside of the NotImplementedException is that if you do somethig like

function train(::AbstractModel, data) 
    throw(NotImplementedException()) 
end

struct GoodModel <: AbstractModel
...
end

function train(mdl::GoodModel, data::Vector) 
...
end

then call
train(mdl, (1,2,3)) (a tuple rather than a vector)
then you get a NotImplementedException with a uninformative error message.

Rather than a MethodError listing what you called, vs what exists

4 Likes