# The Match Operator and Pattern Matching — Elixir & Phoenix

Source: https://www.geekswithgeeks.com/en/elixir-phoenix/c-match

> Use = as a match, destructure data and pin values.

## = is a match, not assignment

In Elixir, **`=` is the match operator**: the left side is a **pattern** that must match the value on the right, binding any variables in it. `x = 1` binds `x`, but `1 = x` is also valid and asserts that `x` is 1, raising **`MatchError`** otherwise. Patterns destructure tuples (`{:ok, user} = fetch()`), lists (`[first | rest] = items`), maps (`%{city: city} = order`, which matches any map containing that key) and binaries (`<<"INV-", number::binary>> = "INV-42"`). The underscore `_` ignores a value, and `_name` documents an ignored variable. The **pin operator `^`** matches against an existing variable's value instead of rebinding: `^expected = actual`. Pattern matching is everywhere in Elixir: in function heads, `case`, `with`, `receive` and comprehensions. A common idiom is matching on **tagged tuples** such as `{:ok, value}` and `{:error, reason}`, so successful and failed results are handled explicitly rather than with exceptions.

## Matching shapes

The pattern on the left must fit the value's shape; variables capture the matching parts.

![A stencil with holes on the left lined up over a structured block on the right, with the parts showing through the holes highlighted.](assets/figures/elixir-phoenix/section-2-map.svg) — Figure 2.1 — A pattern destructuring a value.

## Pattern matching in practice

Tuples, lists, maps, binaries and the pin operator.

```elixir
{:ok, user} = {:ok, %{name: "Asha", tier: :gold}}
IO.puts(user.name)

[first | rest] = ["pen", "ink", "pad"]
IO.inspect({first, rest})                    # {"pen", ["ink", "pad"]}

%{city: city} = %{id: "o-1", city: "Pune", total: 1200}   # extra keys are fine
IO.puts(city)

<<"INV-", number::binary>> = "INV-2026-42"
IO.puts(number)                              # 2026-42

expected = "o-1"
%{id: ^expected} = %{id: "o-1", total: 99}   # pin: must equal the existing value

try do
  {:ok, _} = {:error, :timeout}
rescue
  e in MatchError -> IO.puts("no match: #{inspect(e.term)}")
end

{_ignored, second, _} = {1, 2, 3}
IO.puts(second)
```

## A shape sorter toy

Pattern matching is a child's shape sorter: a block only goes through the hole with the same shape. If you try the star block in the circle hole, it does not fit, and Elixir tells you with a MatchError.

**Quiz:** What does the pin operator ^ do in a pattern?

- [ ] Rebinds the variable
- [ ] Makes the variable global
- [x] Matches against the variable's existing value instead of rebinding it
- [ ] Ignores the value

*Answer:* Matches against the variable's existing value instead of rebinding it. Pinned variables are compared, not rebound.
