Pattern Matching

Elixir variables can be rebound (data stays immutable):

6.1 = is the match operator

x = 1          # binds x to 1
1 = x          # matches! (1 equals x)
2 = x          # ** (MatchError) no match of right hand side value: 1

6.2 Destructuring

{a, b, c} = {:hello, "world", 42}
[head | tail] = [1, 2, 3]       # head = 1, tail = [2, 3]
[first, second | _] = [1, 2, 3, 4]
%{name: name} = %{name: "Ann", age: 30}   # maps match on a subset of keys
{:ok, result} = {:ok, 13}
"Hello " <> rest = "Hello World"          # rest = "World"
<<a, b, rest::binary>> = "abcdef"         # a = 97, b = 98, rest = "cdef"

6.3 The underscore

{_, x, _} = {1, 2, 3}
{_ignored, value} = {:meta, 10}   # named but unused (no warning)

6.4 Rebinding and the pin operator

Elixir variables can be rebound (data stays immutable):

x = 1
x = 2           # rebinding — fine
^x = 2          # pin: match against the CURRENT value of x
^x = 3          # MatchError

key = :name
%{^key => value} = %{name: "Bob"}   # pin in map keys

6.5 Matching in function heads, case, and receive

Pattern matching is everywhere: function clauses, case, with, receive, comprehensions.

6.6 Immutability

All data is immutable; "modifying" returns a new value. Persistent data structures make this efficient.

list = [1, 2, 3]
new_list = [0 | list]   # list unchanged; structure is shared