jonnifyelixir
F3 / F3.06 / define

F3.06 · part 1 of 3

Defining a protocol

defprotocol declares a set of function signatures without bodies — the contract. When one is called, Elixir reads the argument's type and dispatches to the implementation registered for that type. If none exists, the call raises Protocol.UndefinedError.

The portal declares Portal.Summary with one function, summarize/1. Calling it on a value is a lookup by type. Send different values through and watch which implementation the call resolves to.

A call resolves by type

The same call, Portal.Summary.summarize(value), lands in a different module for each type. The portal has implementations for User and Session, but not for a bare integer. Choose a value and follow the dispatch.

The incoming value · select one

INCOMING VALUE %Portal.Accounts.User{email: "ada@portal.dev"} TYPE READ BY THE PROTOCOL Portal.Accounts.User summarize/1 RESOLVES TO Portal.Summary.Portal.Accounts.User

      

A protocol is open: it covers exactly the types that have implementations, and any module can add one later. A type with no implementation is not a silent nil — it is an error at the call.

Declaring the contract

The declaration lists signatures only. The first argument is the value dispatched on; bodies live in the implementations, written next. A protocol can declare more than one function, and every implementation must define all of them.

defprotocol Portal.Summary do
  @doc "A short one-line summary of any portal entity."
  def summarize(value)
end

# a call is a lookup by the value's type
Portal.Summary.summarize(%User{email: "ada@portal.dev", role: :student})
# => dispatches to the User implementation

Portal.Summary.summarize(42)
# ** (Protocol.UndefinedError) protocol Portal.Summary not implemented for 42

F3.05.3 · matching on the tag

A function clause matched %User{} by its __struct__ tag.

F3 · protocol dispatch

The same lookup, built in: the call reads the type and finds the implementation — no clause to write.

Next: implementing for a struct — writing the per-type bodies that a call resolves to.

References

Primary sources for this lesson, and where it connects in the course.

Sources

Related in this course