snippetelixirModeratepending
Elixir Pattern Matching and With Expressions
Viewed 0 times
elixirpattern matchingwith expressionguardspin operatordestructuring
Problem
Elixir's pattern matching and 'with' expressions are powerful but unfamiliar to developers coming from other languages. Nested case statements get unwieldy.
Solution
Pattern matching patterns in Elixir:
# Basic pattern matching
{:ok, result} = {:ok, 42}
[head | tail] = [1, 2, 3] # head = 1, tail = [2, 3]
%{name: name} = %{name: "Alice", age: 30} # name = "Alice"
# Function clause matching
def handle_response({:ok, body}), do: process(body)
def handle_response({:error, reason}), do: log_error(reason)
def handle_response(_), do: :unknown
# Guard clauses
def abs(x) when x >= 0, do: x
def abs(x) when x < 0, do: -x
# Pin operator (match existing value, don't rebind)
x = 1
^x = 1 # matches
^x = 2 # ** (MatchError)
# With expression (replaces nested case)
def create_user(params) do
with {:ok, validated} <- validate(params),
{:ok, user} <- insert_user(validated),
{:ok, _} <- send_welcome_email(user) do
{:ok, user}
else
{:error, :invalid_email} -> {:error, "Invalid email"}
{:error, :duplicate} -> {:error, "User already exists"}
{:error, reason} -> {:error, "Failed: #{reason}"}
end
end
# Struct matching
defmodule User do
defstruct [:name, :email, :role]
end
def admin?(%User{role: :admin}), do: true
def admin?(%User{}), do: falseWhy
Pattern matching eliminates most conditional logic. Instead of checking if-else chains, you declare what shape of data each function clause handles. The runtime picks the right clause.
Gotchas
- Pattern matching in = is a match, not assignment - left side is the pattern
- with expressions short-circuit on first non-match - unmatched values go to else
Context
Writing idiomatic Elixir code
Revisions (0)
No revisions yet.