links: [[Functions in Elixir]]
---
# Guard Clauses
Guards are used as a complement to pattern matching. They allow for more complex checks. They can be used in some, but not all situations where pattern matching can be used, for example in function clauses and case clauses
```elixir
def empty?(list) when is_list(list) and length(list) == 0 do
true
end
```
- Guards begin with `when` keyword, followed by a boolean expression
- Guard expressions are special functions which:
- Must be Pure[^1] and not mutate any global state
- Must return strict `true` or `false` values
- You can define your own guard with `defguard`[^2]
- guard names should start with `is_`
```elixir
defmodule HTTP do
defguard is_success(code) when code >= 200 and code < 300
def handle_response(code) when is_success(code) do
:ok
end
end
```
A function declaration also supports guards and multiple clauses. if a function has several clauses, Elixir will try each clause until it finds one that matches. Here is an implementation that checks if the given number is zero or not
```elixir
defmodule Math do
def zero?(0) do
true
end
def zero?(x) when is_integer(x) do
false
end
end
IO.puts Math.zero?(0) # => true
IO.puts Math.zero?(1) # => false
IO.puts Math.zero?([1, 2, 3]) # => ** (FunctionClauseError)
IO.puts Math.zero?(0.0) # => ** (FunctionClauseError)
```
Giving an argument that does not match any clauses raises an error.
You can write `do:` to have one-liner functions
```elixir
defmodule Math do
def zero?(0) do: true
def zero?(x) when is_integer(x) do: false
end
```
---
tags: #elixir #guards
sources:
- [Guards hexdocs](https://hexdocs.pm/elixir/patterns-and-guards.html#guards)
---
References:
[^1]: https://gist.github.com/tomekowal/16cb4192b73fe9222de9fd09e653c03e
[^2]: https://hexdocs.pm/elixir/Kernel.html#defguard/1