This Invenia blog post is a very good read on this topic in my opinion:
In the case of your example, one simple way to at least document the Animal
interface would be via bare function definitions with docstrings. Something along the lines of:
abstract type Animal end
"return the name of an animal"
function get_name end # notice the absence of parentheses. No method is attached to this function (yet)
"make an animal sound"
function make_sound end
function greet(animal::Animal) # this default method uses the previously defined functions
println("hello "+ get_name(animal))
make_sound(animal);
end
And then any animal implementor can at least have an idea of what to implement by looking at the source code for Animal
:
struct Dog <: Animal name::String end
# these define a specific methods for the functions declared above
get_name(dog::Dog) = dog.name
make_sound(dog::Dog) = println(get_name(dog) + " barks!")
# ... and we get a default `greet` implementation for free
But apart from custom test utilities such as those mentioned in Invenia’s blog post above, most of this relies on good documentation. Examples of well documented interfaces can be found in the Julia manual: