summaryrefslogtreecommitdiff
path: root/devdocs/elisp/destructuring-with-pcase-patterns.html
blob: 1c5d7d5976e4b95740e9151590c0a02d9bbc7614 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 <h4 class="subsection">Destructuring with pcase Patterns</h4>  <p>Pcase patterns not only express a condition on the form of the objects they can match, but they can also extract sub-fields of those objects. For example we can extract 2 elements from a list that is the value of the variable <code>my-list</code> with the following code: </p> <div class="example"> <pre class="example">  (pcase my-list
    (`(add ,x ,y)  (message "Contains %S and %S" x y)))
</pre>
</div> <p>This will not only extract <code>x</code> and <code>y</code> but will additionally test that <code>my-list</code> is a list containing exactly 3 elements and whose first element is the symbol <code>add</code>. If any of those tests fail, <code>pcase</code> will immediately return <code>nil</code> without calling <code>message</code>. </p> <p>Extraction of multiple values stored in an object is known as <em>destructuring</em>. Using <code>pcase</code> patterns allows to perform <em>destructuring binding</em>, which is similar to a local binding (see <a href="local-variables">Local Variables</a>), but gives values to multiple elements of a variable by extracting those values from an object of compatible structure. </p> <p>The macros described in this section use <code>pcase</code> patterns to perform destructuring binding. The condition of the object to be of compatible structure means that the object must match the pattern, because only then the object’s subfields can be extracted. For example: </p> <div class="example"> <pre class="example">  (pcase-let ((`(add ,x ,y) my-list))
    (message "Contains %S and %S" x y))
</pre>
</div> <p>does the same as the previous example, except that it directly tries to extract <code>x</code> and <code>y</code> from <code>my-list</code> without first verifying if <code>my-list</code> is a list which has the right number of elements and has <code>add</code> as its first element. The precise behavior when the object does not actually match the pattern is undefined, although the body will not be silently skipped: either an error is signaled or the body is run with some of the variables potentially bound to arbitrary values like <code>nil</code>. </p> <p>The pcase patterns that are useful for destructuring bindings are generally those described in <a href="backquote-patterns">Backquote Patterns</a>, since they express a specification of the structure of objects that will match. </p> <p>For an alternative facility for destructuring binding, see <a href="sequence-functions#seq_002dlet">seq-let</a>. </p> <dl> <dt id="pcase-let">Macro: <strong>pcase-let</strong> <em>bindings body…</em>
</dt> <dd>
<p>Perform destructuring binding of variables according to <var>bindings</var>, and then evaluate <var>body</var>. </p> <p><var>bindings</var> is a list of bindings of the form <code>(<var>pattern</var> <var>exp</var>)</code>, where <var>exp</var> is an expression to evaluate and <var>pattern</var> is a <code>pcase</code> pattern. </p> <p>All <var>exp</var>s are evaluated first, after which they are matched against their respective <var>pattern</var>, introducing new variable bindings that can then be used inside <var>body</var>. The variable bindings are produced by destructuring binding of elements of <var>pattern</var> to the values of the corresponding elements of the evaluated <var>exp</var>. </p>
</dd>
</dl> <dl> <dt id="pcase-let*">Macro: <strong>pcase-let*</strong> <em>bindings body…</em>
</dt> <dd>
<p>Perform destructuring binding of variables according to <var>bindings</var>, and then evaluate <var>body</var>. </p> <p><var>bindings</var> is a list of bindings of the form <code>(<var>pattern</var>
<var>exp</var>)</code>, where <var>exp</var> is an expression to evaluate and <var>pattern</var> is a <code>pcase</code> pattern. The variable bindings are produced by destructuring binding of elements of <var>pattern</var> to the values of the corresponding elements of the evaluated <var>exp</var>. </p> <p>Unlike <code>pcase-let</code>, but similarly to <code>let*</code>, each <var>exp</var> is matched against its corresponding <var>pattern</var> before processing the next element of <var>bindings</var>, so the variable bindings introduced in each one of the <var>bindings</var> are available in the <var>exp</var>s of the <var>bindings</var> that follow it, additionally to being available in <var>body</var>. </p>
</dd>
</dl> <dl> <dt id="pcase-dolist">Macro: <strong>pcase-dolist</strong> <em>(pattern list) body…</em>
</dt> <dd><p>Execute <var>body</var> once for each element of <var>list</var>, on each iteration performing a destructuring binding of variables in <var>pattern</var> to the values of the corresponding subfields of the element of <var>list</var>. The bindings are performed as if by <code>pcase-let</code>. When <var>pattern</var> is a simple variable, this ends up being equivalent to <code>dolist</code> (see <a href="iteration">Iteration</a>). </p></dd>
</dl> <dl> <dt id="pcase-setq">Macro: <strong>pcase-setq</strong> <em>pattern value…</em>
</dt> <dd><p>Assign values to variables in a <code>setq</code> form, destructuring each <var>value</var> according to its respective <var>pattern</var>. </p></dd>
</dl><div class="_attribution">
  <p class="_attribution-p">
    Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
    <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Destructuring-with-pcase-Patterns.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Destructuring-with-pcase-Patterns.html</a>
  </p>
</div>