InterfaceFunctions
Documentation for InterfaceFunctions.
Features
- Obligatory Interfaces: Define interfaces that all subtypes must implement.
- Optional Interfaces: Provide default implementations that can be overridden.
- Clear Error Messages: Get helpful errors when interfaces are not implemented.
- Debug Logging: See when default implementations are used.
Contents
See the Quick Start for a brief introduction, or the Manual for more detailed examples.
Reference
InterfaceFunctions.UnimplementedInterface — TypeUnimplementedInterface <: ExceptionThrown when a subtype does not implement an obligatory interface.
InterfaceFunctions.@interface — Macro@interface fn_exprDefine an interface function for the abstract type in the first argument of the function signature in fn_expr.
There are two situations in which you would want to use this macro. Both define an interface. The difference is whether you would want to define the interface as obligatory for the implementer or as an optional interface with a default implementation. The use for these two situations differs only in the object on which you apply this macro. If the interface should be obligatory, you call @interface on a function signature. For optional interfaces call the interface macro on the default implementation of the interface.
Obligatory interfaces
An obligatory interface on an abstract type is a way to indicate that every subtype has to provide a custom method for this function. Interfaces are useful for code re-usability in higher order methods. Higher order methods of abstract types can use the interfaces defined on these types to provide implementations for their subtypes.
It is common to define empty functions for obligatory interfaces
function obligatoryfn(a::A, b::B) endThis macro creates the function and adds an informative error message to the user so that he knows what went wrong and how to fix it (what method he has to implement to fix the issue)
"Documentation"
@inteface obligatoryfn(a::A, b::B)roughly translates to
"Documentation"
function obligatoryfn(a::A, b::B)
throw(UnimplementedInterface{A}(#=signature=#))
endOptional interfaces
An optional interface on an abstract type signifies to the developer working with the abstract type that he has the option to change the behaviour of the higher order functions by defining a specialized method for his subtype.
The benefit of using the @interface macro for defining such a function is that it can be then used in the documentation as a group of interfaces that are optional for a type and there are @debug messages added automatically to the calls indicating that the default implementation for the interface is used.
If you want to create an optional interface you have to add the @interface annotation in front of the default implementation
@interface optionalfn(a::A, b::B) = :default
# OR
@interface function optionalfn(a::A, b::B)
return :default
endThese translate roughly to
function optionalfn(a::A, b::B)
@debug "Calling default implementation of $(#=signature=#) at $(#=source=#) for type $(#=caller=#)"
return :default
end