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.
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.
Here is a snippet of a sample implementation of the factorial
function using the guard clause and pattern matching:
defmodule Fact_Guard dodef factorial(0) do1enddef factorial(n) when n > 0 don * factorial(n - 1)endend
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.
Let’s look at the code below:
defmodule Fact_Guard dodef factorial(0) do1enddef factorial(n) when n > 0 don * factorial(n - 1)endend# initial caseIO.puts "Initial Case: #{Fact_Guard.factorial(0)}"# case with postive numberIO.puts "Case with Postive Number: #{Fact_Guard.factorial(5)}"# case with negative numberIO.puts "Case with Negative Number: #{Fact_Guard.factorial(-5)}"
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