Jake Demarest-Mays
← All posts No. 002 ·

Pattern Matching in Elixir

A look at how pattern matching works in Elixir and why it's one of the language's most powerful features.

Pattern matching is one of the first things that feels genuinely different when coming to Elixir from a more imperative background. Once it clicks, it changes how you think about writing code.

The Basics

In Elixir, = is the match operator, not assignment:

{:ok, value} = {:ok, 42}
# value is now 42

{:ok, value} = {:error, "oops"}
# ** (MatchError) no match of right hand side value: {:error, "oops"}

You're not assigning — you're asserting a shape and binding names to parts of it simultaneously.

In Function Heads

This becomes especially powerful in function definitions:

defmodule Greeter do
  def greet(%{name: name, role: :admin}) do
    "Welcome, #{name}. You have admin access."
  end

  def greet(%{name: name}) do
    "Hello, #{name}."
  end

  def greet(_), do: "Hello, stranger."
end

Each clause handles a different shape of input. No conditionals, no if role == :admin. The code reads like a specification.

With case and with

Pattern matching shines in case expressions when handling multiple outcomes:

case fetch_user(id) do
  {:ok, %{role: :admin} = user} -> render_admin(user)
  {:ok, user} -> render_user(user)
  {:error, :not_found} -> send_404()
  {:error, reason} -> log_and_fail(reason)
end

And with chains lets you sequence operations that might fail, only continuing when each step matches:

with {:ok, user} <- fetch_user(id),
     {:ok, account} <- fetch_account(user.account_id),
     :ok <- check_permissions(user, account) do
  render_dashboard(user, account)
else
  {:error, :not_found} -> send_404()
  {:error, :forbidden} -> send_403()
end

Why It Matters

Pattern matching makes the shape of your data explicit in the code itself. It forces you to think about failure cases at the same time as success cases. And it eliminates entire categories of defensive nil checks that accumulate in codebases that lack it.

Once you've worked with it for a while, code without pattern matching starts to feel like working with one hand tied behind your back.