Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-release > by-pkgid > 016232f1d9a3f7bee85855d35a2bca58 > files > 143

elixir-doc-1.7.2-1.mga7.noarch.rpm

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="ExDoc v0.19.1">
    <title>Guards – Elixir v1.7.2</title>
    <link rel="stylesheet" href="dist/app-240d7fc7e5.css" />
      <link rel="canonical" href="https://hexdocs.pm/elixir/v1.7/guards.html" />
    <script src="dist/sidebar_items-cdf4e58b19.js"></script>
    
  </head>
  <body data-type="extras">
    <script>try { if(localStorage.getItem('night-mode')) document.body.className += ' night-mode'; } catch (e) { }</script>
<div class="main">
<button class="sidebar-button sidebar-toggle">
  <span class="icon-menu" aria-hidden="true"></span>
  <span class="sr-only">Toggle Sidebar</span>
</button>
<button class="sidebar-button night-mode-toggle">
  <span class="icon-theme" aria-hidden="true"></span>
  <span class="sr-only">Toggle Theme</span>
</button>
<section class="sidebar">

  <a href="http://elixir-lang.org/docs.html" class="sidebar-projectLink">
    <div class="sidebar-projectDetails">
      <h1 class="sidebar-projectName">
Elixir      </h1>
      <h2 class="sidebar-projectVersion">
        v1.7.2
      </h2>
    </div>
      <img src="assets/logo.png" alt="Elixir" class="sidebar-projectImage">
  </a>

  <form class="sidebar-search" action="search.html">
    <button type="submit" class="search-button">
      <span class="icon-search" aria-hidden="true"></span>
    </button>
    <input name="q" type="text" id="search-list" class="search-input" placeholder="Search" aria-label="Search" autocomplete="off" />
  </form>

  <ul class="sidebar-listNav">
    <li><a id="extras-list" href="#full-list">Pages</a></li>

      <li><a id="modules-list" href="#full-list">Modules</a></li>

      <li><a id="exceptions-list" href="#full-list">Exceptions</a></li>

  </ul>
  <div class="gradient"></div>
  <ul id="full-list" class="sidebar-fullList"></ul>
</section>

<section class="content">
  <div class="content-outer">
    <div id="content" class="content-inner">


<h1>Guards</h1>
<p>Guards are a way to augment pattern matching with more complex checks. They are allowed in a predefined set of constructs where pattern matching is allowed.</p>
<p>Not all expressions are allowed in guard clauses, but only a handful of them. This is a deliberate choice. This way, Elixir (and Erlang) can make sure that nothing bad happens while executing guards and no mutations happen anywhere. It also allows the compiler to optimize the code related to guards efficiently.</p>
<h2 id="list-of-allowed-expressions" class="section-heading">
  <a href="#list-of-allowed-expressions" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  List of allowed expressions
</h2>

<p>For reference, the following is a comprehensive list of all expressions allowed in guards:</p>
<ul>
<li>comparison operators (<a href="Kernel.html#==/2"><code class="inline">==</code></a>, <a href="Kernel.html#!=/2"><code class="inline">!=</code></a>, <a href="Kernel.html#===/2"><code class="inline">===</code></a>, <a href="Kernel.html#!==/2"><code class="inline">!==</code></a>,
<a href="Kernel.html#%253E/2"><code class="inline">&gt;</code></a>, <a href="Kernel.html#%253E=/2"><code class="inline">&gt;=</code></a>, <a href="Kernel.html#%253C/2"><code class="inline">&lt;</code></a>, <a href="Kernel.html#%253C=/2"><code class="inline">&lt;=</code></a>)
</li>
<li><p>strictly boolean operators (<a href="Kernel.html#and/2"><code class="inline">and</code></a>, <a href="Kernel.html#or/2"><code class="inline">or</code></a>, <a href="Kernel.html#not/1"><code class="inline">not</code></a>)</p>
<ul>
<li><strong>NOTE</strong>: <a href="Kernel.html#&amp;amp;&amp;amp;/2"><code class="inline">&amp;&amp;</code></a>, <a href="Kernel.html#%257C%257C/2"><code class="inline">||</code></a>, and <a href="Kernel.html#!/1"><code class="inline">!</code></a> sibling operators are not allowed as they’re not
<em>strictly</em> boolean - meaning they don’t require both sides to be booleans
</li>
</ul>
</li>
<li>arithmetic binary operators (<a href="Kernel.html#+/2"><code class="inline">+</code></a>, <a href="Kernel.html#-/2"><code class="inline">-</code></a>, <a href="Kernel.html#*/2"><code class="inline">*</code></a>, <a href="Kernel.html#//2"><code class="inline">/</code></a>)
</li>
<li>arithmetic unary operators (<a href="Kernel.html#+/1"><code class="inline">+</code></a>, <a href="Kernel.html#-/1"><code class="inline">-</code></a>)
</li>
<li>binary concatenation operator (<a href="Kernel.html#%253C%253E/2"><code class="inline">&lt;&gt;</code></a>)
</li>
<li><a href="Kernel.html#in/2"><code class="inline">in</code></a> and <a href="Kernel.html#in/2"><code class="inline">not in</code></a> operators (as long as the right-hand side is a list or a range)
</li>
<li><p>the following “type-check” functions (all documented in the <a href="Kernel.html"><code class="inline">Kernel</code></a> module):</p>
<ul>
<li><a href="Kernel.html#is_atom/1"><code class="inline">is_atom/1</code></a>
</li>
<li><a href="Kernel.html#is_binary/1"><code class="inline">is_binary/1</code></a>
</li>
<li><a href="Kernel.html#is_bitstring/1"><code class="inline">is_bitstring/1</code></a>
</li>
<li><a href="Kernel.html#is_boolean/1"><code class="inline">is_boolean/1</code></a>
</li>
<li><a href="Kernel.html#is_float/1"><code class="inline">is_float/1</code></a>
</li>
<li><a href="Kernel.html#is_function/1"><code class="inline">is_function/1</code></a>
</li>
<li><a href="Kernel.html#is_function/2"><code class="inline">is_function/2</code></a>
</li>
<li><a href="Kernel.html#is_integer/1"><code class="inline">is_integer/1</code></a>
</li>
<li><a href="Kernel.html#is_list/1"><code class="inline">is_list/1</code></a>
</li>
<li><a href="Kernel.html#is_map/1"><code class="inline">is_map/1</code></a>
</li>
<li><a href="Kernel.html#is_nil/1"><code class="inline">is_nil/1</code></a>
</li>
<li><a href="Kernel.html#is_number/1"><code class="inline">is_number/1</code></a>
</li>
<li><a href="Kernel.html#is_pid/1"><code class="inline">is_pid/1</code></a>
</li>
<li><a href="Kernel.html#is_port/1"><code class="inline">is_port/1</code></a>
</li>
<li><a href="Kernel.html#is_reference/1"><code class="inline">is_reference/1</code></a>
</li>
<li><a href="Kernel.html#is_tuple/1"><code class="inline">is_tuple/1</code></a>
</li>
</ul>
</li>
<li><p>the following guard-friendly functions (all documented in the <a href="Kernel.html"><code class="inline">Kernel</code></a> module):</p>
<ul>
<li><a href="Kernel.html#abs/1"><code class="inline">abs/1</code></a>
</li>
<li><a href="Kernel.html#binary_part/3"><code class="inline">binary_part/3</code></a>
</li>
<li><a href="Kernel.html#bit_size/1"><code class="inline">bit_size/1</code></a>
</li>
<li><a href="Kernel.html#byte_size/1"><code class="inline">byte_size/1</code></a>
</li>
<li><a href="Kernel.html#div/2"><code class="inline">div/2</code></a>
</li>
<li><a href="Kernel.html#elem/2"><code class="inline">elem/2</code></a>
</li>
<li><a href="Kernel.html#hd/1"><code class="inline">hd/1</code></a>
</li>
<li><a href="Kernel.html#length/1"><code class="inline">length/1</code></a>
</li>
<li><a href="Kernel.html#map_size/1"><code class="inline">map_size/1</code></a>
</li>
<li><a href="Kernel.html#node/0"><code class="inline">node/0</code></a>
</li>
<li><a href="Kernel.html#node/1"><code class="inline">node/1</code></a>
</li>
<li><a href="Kernel.html#rem/2"><code class="inline">rem/2</code></a>
</li>
<li><a href="Kernel.html#round/1"><code class="inline">round/1</code></a>
</li>
<li><a href="Kernel.html#self/0"><code class="inline">self/0</code></a>
</li>
<li><a href="Kernel.html#tl/1"><code class="inline">tl/1</code></a>
</li>
<li><a href="Kernel.html#trunc/1"><code class="inline">trunc/1</code></a>
</li>
<li><a href="Kernel.html#tuple_size/1"><code class="inline">tuple_size/1</code></a>
</li>
</ul>
</li>
<li><p>the following handful of Erlang bitwise operations, if imported from the <a href="Bitwise.html"><code class="inline">Bitwise</code></a> module:</p>
<ul>
<li><a href="Bitwise.html#band/2"><code class="inline">band/2</code></a> or the <a href="Bitwise.html#&amp;amp;&amp;amp;&amp;amp;/2"><code class="inline">&amp;&amp;&amp;</code></a> operator
</li>
<li><a href="Bitwise.html#bor/2"><code class="inline">bor/2</code></a> or the <a href="Bitwise.html#%257C%257C%257C/2"><code class="inline">|||</code></a> operator
</li>
<li><a href="Bitwise.html#bnot/1"><code class="inline">bnot/1</code></a> or the <a href="Bitwise.html#~~~/1"><code class="inline">~~~</code></a> operator
</li>
<li><a href="Bitwise.html#bsl/2"><code class="inline">bsl/2</code></a> or the <a href="Bitwise.html#%253C%253C%253C/2"><code class="inline">&lt;&lt;&lt;</code></a> operator
</li>
<li><a href="Bitwise.html#bsr/2"><code class="inline">bsr/2</code></a> or the <a href="Bitwise.html#%253E%253E%253E/2"><code class="inline">&gt;&gt;&gt;</code></a> operator
</li>
<li><a href="Bitwise.html#bxor/2"><code class="inline">bxor/2</code></a> or the <a href="Bitwise.html#%255E%255E%255E/2"><code class="inline">^^^</code></a> operator
</li>
</ul>
</li>
</ul>
<p>Macros constructed out of any combination of the above guards are also valid guards - for example, <a href="Integer.html#is_even/1"><code class="inline">Integer.is_even/1</code></a>. See the section “Defining custom guard expressions” below.</p>
<h2 id="why-guards" class="section-heading">
  <a href="#why-guards" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  Why guards
</h2>

<p>Let’s see an example of a guard used in a function clause:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">empty_map?</span><span class="p" data-group-id="6508042386-1">(</span><span class="n">map</span><span class="p" data-group-id="6508042386-1">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">map_size</span><span class="p" data-group-id="6508042386-2">(</span><span class="n">map</span><span class="p" data-group-id="6508042386-2">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="no">true</span><span class="w">
</span><span class="kd">def</span><span class="w"> </span><span class="nf">empty_map?</span><span class="p" data-group-id="6508042386-3">(</span><span class="n">map</span><span class="p" data-group-id="6508042386-3">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_map</span><span class="p" data-group-id="6508042386-4">(</span><span class="n">map</span><span class="p" data-group-id="6508042386-4">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="no">false</span></code></pre>
<p>Guards start with the <code class="inline">when</code> keyword, which is followed by a boolean expression (we will define the grammar of guards more formally later on).</p>
<p>Writing the <code class="inline">empty_map?/1</code> function by only using pattern matching would not be possible (as pattern matching on <code class="inline">%{}</code> would match <em>every</em> map, not empty maps).</p>
<h2 id="where-guards-can-be-used" class="section-heading">
  <a href="#where-guards-can-be-used" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  Where guards can be used
</h2>

<p>In the example above, we show how guards can be used in function clauses. There are several constructs that allow guards; for example:</p>
<ul>
<li>function clauses:
</li>
</ul>
<pre><code class="nohighlight makeup elixir"><span class="w">  </span><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="4716153417-1">(</span><span class="n">term</span><span class="p" data-group-id="4716153417-1">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="4716153417-2">(</span><span class="n">term</span><span class="p" data-group-id="4716153417-2">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">term</span><span class="w">
  </span><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="4716153417-3">(</span><span class="n">term</span><span class="p" data-group-id="4716153417-3">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_float</span><span class="p" data-group-id="4716153417-4">(</span><span class="n">term</span><span class="p" data-group-id="4716153417-4">)</span><span class="p">,</span><span class="w"> </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="n">round</span><span class="p" data-group-id="4716153417-5">(</span><span class="n">term</span><span class="p" data-group-id="4716153417-5">)</span></code></pre>
<ul>
<li><a href="Kernel.SpecialForms.html#case/2"><code class="inline">case</code></a> expressions:
</li>
</ul>
<pre><code class="nohighlight makeup elixir"><span class="w">  </span><span class="k">case</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k" data-group-id="9972486834-1">do</span><span class="w">
    </span><span class="mi">1</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="ss">:one</span><span class="w">
    </span><span class="mi">2</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="ss">:two</span><span class="w">
    </span><span class="n">n</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="9972486834-2">(</span><span class="n">n</span><span class="p" data-group-id="9972486834-2">)</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="ss">:larger_than_two</span><span class="w">
  </span><span class="k" data-group-id="9972486834-1">end</span></code></pre>
<ul>
<li>anonymous functions (<a href="Kernel.SpecialForms.html#fn/1"><code class="inline">fn</code></a>s):
</li>
</ul>
<pre><code class="nohighlight makeup elixir"><span class="w">  </span><span class="n">larger_than_two?</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k" data-group-id="5048084412-1">fn</span><span class="w">
    </span><span class="n">n</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="5048084412-2">(</span><span class="n">n</span><span class="p" data-group-id="5048084412-2">)</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="no">true</span><span class="w">
    </span><span class="n">n</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="5048084412-3">(</span><span class="n">n</span><span class="p" data-group-id="5048084412-3">)</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="no">false</span><span class="w">
  </span><span class="k" data-group-id="5048084412-1">end</span></code></pre>
<ul>
<li>custom guards can also be defined with <a href="Kernel.html#defguard/1"><code class="inline">Kernel.defguard/1</code></a> and <a href="Kernel.html#defguardp/1"><code class="inline">Kernel.defguardp/1</code></a>.
A custom guard is always defined based on existing guards.
</li>
</ul>
<p>Other constructs are <a href="Kernel.SpecialForms.html#for/1"><code class="inline">for</code></a>, <a href="Kernel.SpecialForms.html#with/1"><code class="inline">with</code></a>, <a href="Kernel.SpecialForms.html#try/1"><code class="inline">try/rescue/catch/else</code></a>, and the <a href="Kernel.html#match?/2"><code class="inline">Kernel.match?/2</code></a>.</p>
<h2 id="failing-guards" class="section-heading">
  <a href="#failing-guards" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  Failing guards
</h2>

<p>In guards, when functions would normally raise exceptions, they cause the guard to fail instead.
For example, the <a href="Kernel.html#length/1"><code class="inline">length/1</code></a> function only works with lists. If we use it with anything else, a runtime error is raised:</p>
<pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex&gt; </span><span class="n">length</span><span class="p" data-group-id="6768589936-1">(</span><span class="s">&quot;hello&quot;</span><span class="p" data-group-id="6768589936-1">)</span><span class="w">
</span><span class="gt">** (ArgumentError) argument error</span></code></pre>
<p>However, when used in guards, the corresponding clause simply fails to match:</p>
<pre><code class="nohighlight makeup elixir"><span class="gp unselectable">iex&gt; </span><span class="k">case</span><span class="w"> </span><span class="s">&quot;hello&quot;</span><span class="w"> </span><span class="k" data-group-id="8679726574-1">do</span><span class="w">
</span><span class="gp unselectable">...&gt; </span><span class="w">  </span><span class="n">something</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">length</span><span class="p" data-group-id="8679726574-2">(</span><span class="n">something</span><span class="p" data-group-id="8679726574-2">)</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">-&gt;</span><span class="w">
</span><span class="gp unselectable">...&gt; </span><span class="w">    </span><span class="ss">:length_worked</span><span class="w">
</span><span class="gp unselectable">...&gt; </span><span class="w">  </span><span class="c">_anything_else</span><span class="w"> </span><span class="o">-&gt;</span><span class="w">
</span><span class="gp unselectable">...&gt; </span><span class="w">    </span><span class="ss">:length_failed</span><span class="w">
</span><span class="gp unselectable">...&gt; </span><span class="k" data-group-id="8679726574-1">end</span><span class="w">
</span><span class="ss">:length_failed</span></code></pre>
<p>In many cases, we can take advantage of this. In the code above, we used <a href="Kernel.html#length/1"><code class="inline">length/1</code></a> to both check that the given thing is a list <em>and</em> check some properties of its length (instead of using <code class="inline">is_list(something) and length(something) &gt; 0</code>).</p>
<h2 id="defining-custom-guard-expressions" class="section-heading">
  <a href="#defining-custom-guard-expressions" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  Defining custom guard expressions
</h2>

<p>As mentioned before, only the expressions listed in this page are allowed in guards. However, we can take advantage of macros to write custom guards that can simplify our programs or make them more domain-specific. At the end of the day, what matters is that the <em>output</em> of the macros (which is what will be compiled) boils down to a combinations of the allowed expressions.</p>
<p>Let’s look at a quick case study: we want to check that a function argument is an even or odd integer. With pattern matching, this is impossible to do since there are infinite integers, and thus we can’t pattern match on the single even/odd numbers. Let’s focus on checking for even numbers since checking for odd ones is almost identical.</p>
<p>Such a guard would look like this:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">my_function</span><span class="p" data-group-id="1649317697-1">(</span><span class="n">number</span><span class="p" data-group-id="1649317697-1">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="1649317697-2">(</span><span class="n">number</span><span class="p" data-group-id="1649317697-2">)</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">rem</span><span class="p" data-group-id="1649317697-3">(</span><span class="n">number</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p" data-group-id="1649317697-3">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k" data-group-id="1649317697-4">do</span><span class="w">
  </span><span class="c1"># do stuff</span><span class="w">
</span><span class="k" data-group-id="1649317697-4">end</span></code></pre>
<p>This would be repetitive to write every time we need this check, so, as mentioned at the beginning of this section, we can abstract this away using a macro. Remember that defining a function that performs this check wouldn’t work because we can’t use custom functions in guards. Our macro would look like this:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">defmodule</span><span class="w"> </span><span class="nc">MyInteger</span><span class="w"> </span><span class="k" data-group-id="0068021511-1">do</span><span class="w">
  </span><span class="kd">defmacro</span><span class="w"> </span><span class="nf">is_even</span><span class="p" data-group-id="0068021511-2">(</span><span class="n">number</span><span class="p" data-group-id="0068021511-2">)</span><span class="w"> </span><span class="k" data-group-id="0068021511-3">do</span><span class="w">
    </span><span class="k">quote</span><span class="w"> </span><span class="k" data-group-id="0068021511-4">do</span><span class="w">
      </span><span class="n">is_integer</span><span class="p" data-group-id="0068021511-5">(</span><span class="k">unquote</span><span class="p" data-group-id="0068021511-6">(</span><span class="n">number</span><span class="p" data-group-id="0068021511-6">)</span><span class="p" data-group-id="0068021511-5">)</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">rem</span><span class="p" data-group-id="0068021511-7">(</span><span class="k">unquote</span><span class="p" data-group-id="0068021511-8">(</span><span class="n">number</span><span class="p" data-group-id="0068021511-8">)</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p" data-group-id="0068021511-7">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w">
    </span><span class="k" data-group-id="0068021511-4">end</span><span class="w">
  </span><span class="k" data-group-id="0068021511-3">end</span><span class="w">
</span><span class="k" data-group-id="0068021511-1">end</span></code></pre>
<p>and then:</p>
<pre><code class="nohighlight makeup elixir"><span class="kn">import</span><span class="w"> </span><span class="nc">MyInteger</span><span class="p">,</span><span class="w"> </span><span class="ss">only</span><span class="p">:</span><span class="w"> </span><span class="p" data-group-id="6390253242-1">[</span><span class="ss">is_even</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p" data-group-id="6390253242-1">]</span><span class="w">

</span><span class="kd">def</span><span class="w"> </span><span class="nf">my_function</span><span class="p" data-group-id="6390253242-2">(</span><span class="n">number</span><span class="p" data-group-id="6390253242-2">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_even</span><span class="p" data-group-id="6390253242-3">(</span><span class="n">number</span><span class="p" data-group-id="6390253242-3">)</span><span class="w"> </span><span class="k" data-group-id="6390253242-4">do</span><span class="w">
  </span><span class="c1"># do stuff</span><span class="w">
</span><span class="k" data-group-id="6390253242-4">end</span></code></pre>
<p>While it’s possible to create custom guards with macros, it’s recommended to define them using <code class="inline">defguard</code> and <code class="inline">defguardp</code> which perform additional compile-time checks. Here’s an example:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">defmodule</span><span class="w"> </span><span class="nc">MyInteger</span><span class="w"> </span><span class="k" data-group-id="5317997178-1">do</span><span class="w">
  </span><span class="kd">defguard</span><span class="w"> </span><span class="nf">is_even</span><span class="p" data-group-id="5317997178-2">(</span><span class="n">value</span><span class="p" data-group-id="5317997178-2">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="5317997178-3">(</span><span class="n">value</span><span class="p" data-group-id="5317997178-3">)</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">rem</span><span class="p" data-group-id="5317997178-4">(</span><span class="n">value</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p" data-group-id="5317997178-4">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span><span class="k" data-group-id="5317997178-1">end</span></code></pre>
<h2 id="multiple-guards-in-the-same-clause" class="section-heading">
  <a href="#multiple-guards-in-the-same-clause" class="hover-link"><span class="icon-link" aria-hidden="true"></span></a>
  Multiple guards in the same clause
</h2>

<p>There exists an additional way to simplify a chain of <code class="inline">or</code>s in guards: Elixir supports writing “multiple guards” in the same clause. This:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="7171555641-1">(</span><span class="n">term</span><span class="p" data-group-id="7171555641-1">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="7171555641-2">(</span><span class="n">term</span><span class="p" data-group-id="7171555641-2">)</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">is_float</span><span class="p" data-group-id="7171555641-3">(</span><span class="n">term</span><span class="p" data-group-id="7171555641-3">)</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">is_nil</span><span class="p" data-group-id="7171555641-4">(</span><span class="n">term</span><span class="p" data-group-id="7171555641-4">)</span><span class="p">,</span><span class="w">
  </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="ss">:maybe_number</span><span class="w">
</span><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="7171555641-5">(</span><span class="c">_other</span><span class="p" data-group-id="7171555641-5">)</span><span class="p">,</span><span class="w">
  </span><span class="ss">do</span><span class="p">:</span><span class="w"> </span><span class="ss">:something_else</span></code></pre>
<p>can be alternatively written as:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="1006239321-1">(</span><span class="n">term</span><span class="p" data-group-id="1006239321-1">)</span><span class="w">
    </span><span class="ow">when</span><span class="w"> </span><span class="n">is_integer</span><span class="p" data-group-id="1006239321-2">(</span><span class="n">term</span><span class="p" data-group-id="1006239321-2">)</span><span class="w">
    </span><span class="ow">when</span><span class="w"> </span><span class="n">is_float</span><span class="p" data-group-id="1006239321-3">(</span><span class="n">term</span><span class="p" data-group-id="1006239321-3">)</span><span class="w">
    </span><span class="ow">when</span><span class="w"> </span><span class="n">is_nil</span><span class="p" data-group-id="1006239321-4">(</span><span class="n">term</span><span class="p" data-group-id="1006239321-4">)</span><span class="w"> </span><span class="k" data-group-id="1006239321-5">do</span><span class="w">
  </span><span class="ss">:maybe_number</span><span class="w">
</span><span class="k" data-group-id="1006239321-5">end</span><span class="w">

</span><span class="kd">def</span><span class="w"> </span><span class="nf">foo</span><span class="p" data-group-id="1006239321-6">(</span><span class="c">_other</span><span class="p" data-group-id="1006239321-6">)</span><span class="w"> </span><span class="k" data-group-id="1006239321-7">do</span><span class="w">
  </span><span class="ss">:something_else</span><span class="w">
</span><span class="k" data-group-id="1006239321-7">end</span></code></pre>
<p>For most cases, the two forms are exactly the same. However, there exists a subtle difference in the case of failing guards, as discussed in the section above.
In case of a boolean expression guard, a failed element means the whole guard fails. In case of multiple guards it means the next one will be evaluated.
The difference can be highlighted with an example:</p>
<pre><code class="nohighlight makeup elixir"><span class="kd">def</span><span class="w"> </span><span class="nf">multiguard</span><span class="p" data-group-id="5987415455-1">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-1">)</span><span class="w">
    </span><span class="ow">when</span><span class="w"> </span><span class="n">map_size</span><span class="p" data-group-id="5987415455-2">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-2">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w">
    </span><span class="ow">when</span><span class="w"> </span><span class="n">tuple_size</span><span class="p" data-group-id="5987415455-3">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-3">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k" data-group-id="5987415455-4">do</span><span class="w">
  </span><span class="ss">:guard_passed</span><span class="w">
</span><span class="k" data-group-id="5987415455-4">end</span><span class="w">
</span><span class="kd">def</span><span class="w"> </span><span class="nf">multiguard</span><span class="p" data-group-id="5987415455-5">(</span><span class="c">_value</span><span class="p" data-group-id="5987415455-5">)</span><span class="w"> </span><span class="k" data-group-id="5987415455-6">do</span><span class="w">
  </span><span class="ss">:guard_failed</span><span class="w">
</span><span class="k" data-group-id="5987415455-6">end</span><span class="w">

</span><span class="kd">def</span><span class="w"> </span><span class="nf">boolean</span><span class="p" data-group-id="5987415455-7">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-7">)</span><span class="w"> </span><span class="ow">when</span><span class="w"> </span><span class="n">map_size</span><span class="p" data-group-id="5987415455-8">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-8">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="ow">or</span><span class="w"> </span><span class="n">tuple_size</span><span class="p" data-group-id="5987415455-9">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-9">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="k" data-group-id="5987415455-10">do</span><span class="w">
  </span><span class="ss">:guard_passed</span><span class="w">
</span><span class="k" data-group-id="5987415455-10">end</span><span class="w">
</span><span class="kd">def</span><span class="w"> </span><span class="nf">boolean</span><span class="p" data-group-id="5987415455-11">(</span><span class="n">value</span><span class="p" data-group-id="5987415455-11">)</span><span class="w"> </span><span class="k" data-group-id="5987415455-12">do</span><span class="w">
  </span><span class="ss">:guard_failed</span><span class="w">
</span><span class="k" data-group-id="5987415455-12">end</span><span class="w">

</span><span class="n">multiguard</span><span class="p" data-group-id="5987415455-13">(</span><span class="p" data-group-id="5987415455-14">%{</span><span class="p" data-group-id="5987415455-14">}</span><span class="p" data-group-id="5987415455-13">)</span><span class="w"> </span><span class="c1">#=&gt; :guard_passed</span><span class="w">
</span><span class="n">multiguard</span><span class="p" data-group-id="5987415455-15">(</span><span class="p" data-group-id="5987415455-16">{</span><span class="p" data-group-id="5987415455-16">}</span><span class="p" data-group-id="5987415455-15">)</span><span class="w">  </span><span class="c1">#=&gt; :guard_passed</span><span class="w">

</span><span class="n">boolean</span><span class="p" data-group-id="5987415455-17">(</span><span class="p" data-group-id="5987415455-18">%{</span><span class="p" data-group-id="5987415455-18">}</span><span class="p" data-group-id="5987415455-17">)</span><span class="w"> </span><span class="c1">#=&gt; :guard_passed</span><span class="w">
</span><span class="n">boolean</span><span class="p" data-group-id="5987415455-19">(</span><span class="p" data-group-id="5987415455-20">{</span><span class="p" data-group-id="5987415455-20">}</span><span class="p" data-group-id="5987415455-19">)</span><span class="w">  </span><span class="c1">#=&gt; :guard_failed</span></code></pre>
<p>For cases where guards do not rely on the failing guard behavior the two forms are exactly the same semantically but there are cases where multiple guard clauses may be more aesthetically pleasing.</p>
      <footer class="footer">
        <p>
          <span class="line">
            Built using
            <a href="https://github.com/elixir-lang/ex_doc" title="ExDoc" target="_blank" rel="help noopener">ExDoc</a> (v0.19.1),
          </span>
          <span class="line">
            designed by
            <a href="https://twitter.com/dignifiedquire" target="_blank" rel="noopener" title="@dignifiedquire">Friedel Ziegelmayer</a>.
            </span>
        </p>
      </footer>
    </div>
  </div>
</section>
</div>
  <script src="dist/app-a0c90688fa.js"></script>
  
  </body>
</html>