What are guard clauses in Elixir?

Overview

Pattern matching allows Elixir to determine which function to invoke based on the arguments passed.

But what if we need to discriminate based on their types or some test concerning their values? For this, guard clauses come in to play this role.

Guard clauses

A guard clause is a fragment of code covering a function or method, which returns early when some precondition is met.

It is a fact that we can lessen both the complexity and cognitive load of code by using them competently. These predicates are connected to a function definition using more when keywords.

While pattern matching, firstly, Elixir does the matching based on the classic parameters, then assesses the predicates and executes the function if any predicate is factual.

Guard clauses are usually favored to when followed by the condition. For example, we have n > 0, as shown in the example below. Due to their readability, that makes a particular optimization procedure easier for the compiler.

Example: Compute factorial

Here is a snippet of a sample implementation of the factorial function using the guard clause and pattern matching:

defmodule Fact_Guard do
def factorial(0) do
1
end
def factorial(n) when n > 0 do
n * factorial(n - 1)
end
end

In the following executable, the initial pattern meets if and only if the parameter passed is 0. If the parameter passed is not 0, the pattern match fails, and the second implementation of the factorial function (at line 5) is checked.

The second function definition has a condition, when n > 0, which guards the clause. It means this function only matches if the argument n is greater than 0.

Note: The mathematical factorial function is not specified for negative integers.

If none of the function definitions (including pattern matching and guard clauses) match, FunctionClauseError is raised. If we pass a negative number as the parameter, the example above raises this error because the factorial function is not prescribed for negative numbers.

Code

Let’s look at the code below:

defmodule Fact_Guard do
def factorial(0) do
1
end
def factorial(n) when n > 0 do
n * factorial(n - 1)
end
end
# initial case
IO.puts "Initial Case: #{Fact_Guard.factorial(0)}"
# case with postive number
IO.puts "Case with Postive Number: #{Fact_Guard.factorial(5)}"
# case with negative number
IO.puts "Case with Negative Number: #{Fact_Guard.factorial(-5)}"

Explanation

  • Line 10: We call the factorial function with 0 as an argument. We get the output 1 because this is our base case.

  • Line 12: We again call the factorial function with 5 as an argument. We get the output 120 because this time, the second implementation of factorial (at line 5) gets called.

  • Line 14: We again call the factorial function with -5 as an argument. We get an error message because the factorial of a negative number is not specified.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved