Forcing users to implements all methods in an abstract interface

Let us assume that we have an abstract type

abstract type Person end

and we want that the following queries are available to all Person types:

sayhello(::Person)::String
saybyebye(::Person)::String

My current approach (inspired by https://github.com/JuliaLang/julia/issues/6975) to force the users to implement these two queries is to define a macro

macro abstractmethod()
  quote
    error("This function belongs to an interface definition and cannot be used.")
  end
end

and then define

sayhello(::Person)::String = @abstractmethod
saybyebye(::Person)::String = @abstractmethod

Then, if we define, e.g.,

struct AncientRomanPerson <: Person end
sayhello(::AncientRomanPerson) = "Salvete omnes!"

but we forget to implement saybyebye(::AncientRomanPerson), we will get an error:

julius = AnceientRomanPerson()
sayhello(julius) # -> Salvete omnes! 
saybyebye(julius) # -> error!!

My question is: is there any way to get an error before the saybyebye method is called? Namely, when the instance julius is created??

In python this is possible using the abc package that provides the ABC class and the @abstractmethod decorator…

If someone thinks that it is a good idea (and it is possible) to implement something similar in julia to the abc python package, I would help with pleasure.

Thanks for the help!

1 Like

Effectively, you are asking Julia to do static checks.

This is not how the language was designed.

I think that even with the macro, you are overthinking it. If a type that should implement an interface doesn’t, then that’s a bug in the code that defines the type and should just be fixed. MethodError is fine for that purpose.

Perhaps in the package that introduces the API, you can just provide a function that helps unit testing an interface.

1 Like

A pattern that works well for me is to use unit tests: implement a testisperson function that checks all the interface is implemented.

PS your abstractmethod macro could just be a function.

3 Likes