I am having some trouble understanding the difference between Behaviours and Protocols. This mostly is caused because the built-in
Access functionality in Elixir is a Behaviour instead of a Protocol.
The odd thing is, that it seems that everything that a protocol does can be made using a Behaviour. Can someone shine light on what is going on?
- Someone defines a protocol using
defprotocol, which has a name and one or multiple functions that need to be implemented (with the given arity). The first argument passed to these function implementations will always be the ‘thing’ that the Protocol is implemented on.
- In another module, someone defines an implementation for this protocol using
Dispatching from the function call to the protocol implementations is automatic.
It is not possible to call the implementations directly on the final module, as they are secretly defined in another place that you cannot access yourself. Therefore, it also does not make sense to document the implemented functions.
- Someone defines a
behaviourby just making a module and having multiple
@callbackstatements in there, that take a spec; It seems that behaviours not only try to validate the arity of the callback implementations, but also e.g. the formats of the input/output data.
- To implement a behaviour, someone has to add
use ModuleWithTheCallbackStatementsto some module, and then simply define the callbacks of that behaviour in that module as functions.
Dispatching happens manually inside the module defining the behaviour (using e.g. for structs the module name inside the struct field); The callbacks may (using
defoverridable) or may not be defined as functions in the module defining the Behaviour. This means that it is a lot easier to treat certain function inputs as ‘special’.
The implemented functions of a behaviour are simply defined and fully accessible and callable as normal functions. As such, they ought to be documented.
It seems to me that Behaviours are more flexible than Protocols. When is it a good idea to implement a Protocol rather than a Behaviour? Are there differences I’ve missed?