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