Polymorphism
Protocol
Protocol is a manchanism for dispatching behavior based on data type, kind of like interface in other languages.
defprotocol Speak do
def speak(data)
end
defmodule Dog do
defstruct [:name]
end
defimpl Speak, for: Dog do
def speak(%Dog{name: name}), do: "#{name} says woof!"
end
Speak.speak(%Dog{name: "Rex"})
# "Rex says woof!"
Elixir's Protocol is conceptually similar to Clojure's protocol:
(defprotocol Speak
(speak [this]))
(defrecord Dog [name])
(extend-type Dog
Speak
(speak [{:keys [name]}]
(str name " says woof!")))
(let [rex (->Dog "Rex")]
(speak rex))
Behavior
Behaviour is a formal way to define interfaces that modules should implement.
defmodule MyBehaviour do
@callback hello(String.t()) :: String.t()
end
defmodule MyModule do
@behaviour MyBehaviour
@impl MyBehaviour
def hello(name), do: "Hello, #{name}"
end
Behaviour conformance is checked at compile time. The compiler will warn if any required callback is missing or arity doesn't match.