Protocols in Elixir

Contents
Define a protocol
Implement it
Derive cheaply
Dispatch on type

Define a protocol

A protocol declares functions that many types can implement in their own way. You define it with defprotocol and list the function heads without bodies, much like a contract for later modules.

defprotocol Sized do def size(value) end

Sized promises one function named size that accepts any value. No type can use it yet, because each type still needs its own implementation.

Implement it

An implementation connects a protocol to one concrete type with defimpl and the for option. Inside the block you write normal function bodies for each promised function.

defimpl Sized, for: List do def size(list) do length(list) end end

Sized.size applied to a three element list now returns 3 by counting list elements. Each new type gets its own defimpl block, so List logic never mixes with text or number logic.

Derive cheaply

Writing a full implementation for a simple struct feels heavy, so some protocols offer deriving. A derive annotation on the struct generates a stock implementation at compile time.

defmodule Point do @derive {Inspect, only: [:x]} defstruct [:x, :y] end

Inspecting a Point now shows only the x field, which keeps logs short while y stays hidden. Deriving works only for protocols that ship a derivation, with Inspect as the everyday example.

Dispatch on type

Calling a protocol function picks the implementation that matches the value type at runtime. The caller names the protocol once, and Elixir routes lists one way and text another way.

defimpl Sized, for: BitString do def size(text) do String.length(text) end end Sized.size([1, 2, 3]) Sized.size("hello")

The first call returns 3 and the second returns 5, even though both use the same Sized.size name. This runtime routing is called dispatch, and it is the heart of every protocol.

Next: Behaviours in Elixir

Article author: Arthur Isaev

Related articles
Elixir
Elixir course: zero to hero in 50 lessons
What is Elixir and where it runs
Install Elixir
iex: the interactive shell
Your first script
Variables
Numbers
Strings
Atoms
Truthiness: only false and nil
Conditions
Recursion replaces loops
Lists
Tuples
Maps
Keyword lists
Functions
Defaults and clauses
Pattern matching
case
with chains
Modules in Elixir
import, alias, require, use in Elixir
Structs in Elixir
Protocols in Elixir
Behaviours in Elixir
The pipe operator in Elixir
Enum in Elixir
Stream in Elixir
Comprehensions in Elixir
Advanced strings in Elixir
Sigils
Binaries and charlists
Exceptions
ok and error tuples
Files and IO
Processes
GenServer
Supervisors
Tasks and Agents
OTP applications
Mix projects
Dependencies
Testing with ExUnit
Doctests
Debugging
Configs
Releases
Capstone: todo CLI
Capstone: HTTP server
Hero roadmap: the whole course on one page
Install Elixir on Windows 11
Install Elixir on Ubuntu
Install Elixir on Rocky Linux
Install Elixir on macOS
Install Elixir on FreeBSD
Elixir in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: