We can use pattern matching in named functions. See the Sum.to function below, which sums up the numbers from 1 to n:
defmodule Sum do
def to(1), do: 1
def to(n), do: n + to(n-1)
endUnfortunately, the above implementation of Sum.to will not work for negative numbers. In fact, if you try to run Sum.to -1, we’ll be stuck in a loop.
We want to specify additional predicates regarding the value or type of the arguments that are passed into our function.
For
Sum.to, we want to make sure thatnis a strictly nonzero positive integer.
Time to use guard clauses:
defmodule Sum do
def to(1), do: 1
def to(n) when n > 0, do: n + to(n-1) # only nonzero positive numbers
endWe can have multiple guard clauses:
defmodule Sum do
def to(1), do: 1
def to(n) when n > 0 and is_integer(n), do: n + to(n-1) # only nonzero positive integers
endNote that the expressions you can use as guard clauses are limited. You can’t use your own functions as Elixir optimizes these clauses for performance reasons. A full list of available expressions are available here.