All posts

Pattern matching changed how I write code

  • #elixir
  • #patterns

The feature I miss most when I leave Elixir isn’t the concurrency model or the pipe operator — it’s pattern matching. Once it clicks, branching code starts to feel clumsy by comparison.

Destructure at the door

Instead of pulling values out inside a function, you match them in the signature:

def greet(%{name: name, role: "admin"}), do: "Welcome back, #{name}"
def greet(%{name: name}), do: "Hi, #{name}"

The shape of the data is the control flow. There’s no if user.role == ... buried three lines down — the dispatch happens before the body even runs.

Let it crash

Matching also doubles as an assertion:

{:ok, result} = do_work()

If do_work/0 returns an error tuple, this line fails loudly and immediately, right where the wrong assumption lives — not five functions later with a nil that’s hard to trace. Combined with supervisors, “let it crash” stops being reckless and starts being a design.

The takeaway

Pattern matching pushed me to model data more deliberately in every language — to make the shape of a value carry meaning, and to fail close to the mistake. That habit travels, even when the syntax doesn’t.