Guard Clauses in Elixir

Published October 01, 2018 by Toran Billups

In part 8 of my Elixir journey I decided to share about using guard clauses in the language.

Guard Clauses

Pattern matching allows us to side step traditional branching logic by inspecting the parameters we pass to a given function.

    defmodule Math do
      def add_one(n) do
        n + 1
      end
    end
  

In this example, the `n` variable is our only criteria and it works great when we call `add_one` with any integer value.

    Math.add_one(1)
  

But what happens when we call it with a string instead?

    Math.add_one("x")
  

`ArithmeticError bad argument in arithmetic expression`

So my first thought was "I need a default function definition for `add_one` and pattern matching will come to my rescue..."

    defmodule Math do
      def add_one(n) do
        n + 1
      end
      def add_one(_), do: IO.puts "yolo"
    end
  

To my surprise I got the same `ArithmeticError`

    Math.add_one("x")
  

It turns out the first function definition is a match for both integer and string values so pattern matching alone won't prevent us from going down that code path. This is a great use case for the guard clause in Elixir! When you need to ask a question about the parameter before you execute a function you can use the `when` keyword to further clarify what is required to use it.

    defmodule Math do
      def add_one(n) when is_integer(n) do
        n + 1
      end
      def add_one(_), do: IO.puts "yolo"
    end
  

This guard clause is using a built-in Erlang function to ask if the parameter `n` is the correct type. The order of operations here is still pattern match first, guard clause second. So in this example the match does work but the string `x` does not return truthy when the guard clause is evaluated. As a result, Elixir will attempt to match using the second `add_one` function definition. Because this function definition takes any parameter the match is a success and the `IO.puts` is executed.


Buy Me a Coffee

Twitter / Github / Email