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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
<h4 class="subsection">The pcase macro</h4> <p>For background, See <a href="pattern_002dmatching-conditional">Pattern-Matching Conditional</a>. </p> <dl> <dt id="pcase">Macro: <strong>pcase</strong> <em>expression &rest clauses</em>
</dt> <dd>
<p>Each clause in <var>clauses</var> has the form: <code>(<var>pattern</var> <var><span class="nolinebreak">body-forms</span></var>…)</code>. </p> <p>Evaluate <var>expression</var> to determine its value, <var>expval</var>. Find the first clause in <var>clauses</var> whose <var>pattern</var> matches <var>expval</var> and pass control to that clause’s <var>body-forms</var>. </p> <p>If there is a match, the value of <code>pcase</code> is the value of the last of <var>body-forms</var> in the successful clause. Otherwise, <code>pcase</code> evaluates to <code>nil</code>. </p>
</dd>
</dl> <p>Each <var>pattern</var> has to be a <em>pcase pattern</em>, which can use either one of the core patterns defined below, or one of the patterns defined via <code>pcase-defmacro</code> (see <a href="extending-pcase">Extending pcase</a>). </p> <p>The rest of this subsection describes different forms of core patterns, presents some examples, and concludes with important caveats on using the let-binding facility provided by some pattern forms. A core pattern can have the following forms: </p> <dl compact> <dt><code>_<span class="roman"> (underscore)</span></code></dt> <dd>
<p>Matches any <var>expval</var>. This is also known as <em>don’t care</em> or <em>wildcard</em>. </p> </dd> <dt><code>'<var>val</var></code></dt> <dd>
<p>Matches if <var>expval</var> equals <var>val</var>. The comparison is done as if by <code>equal</code> (see <a href="equality-predicates">Equality Predicates</a>). </p> </dd> <dt><code><var>keyword</var></code></dt> <dt><code><var>integer</var></code></dt> <dt><code><var>string</var></code></dt> <dd>
<p>Matches if <var>expval</var> equals the literal object. This is a special case of <code>'<var>val</var></code>, above, possible because literal objects of these types are self-quoting. </p> </dd> <dt><code><var>symbol</var></code></dt> <dd>
<p>Matches any <var>expval</var>, and additionally let-binds <var>symbol</var> to <var>expval</var>, such that this binding is available to <var>body-forms</var> (see <a href="dynamic-binding">Dynamic Binding</a>). </p> <p>If <var>symbol</var> is part of a sequencing pattern <var>seqpat</var> (e.g., by using <code>and</code>, below), the binding is also available to the portion of <var>seqpat</var> following the appearance of <var>symbol</var>. This usage has some caveats, see <a href="#pcase_002dsymbol_002dcaveats">caveats</a>. </p> <p>Two symbols to avoid are <code>t</code>, which behaves like <code>_</code> (above) and is deprecated, and <code>nil</code>, which signals an error. Likewise, it makes no sense to bind keyword symbols (see <a href="constant-variables">Constant Variables</a>). </p> </dd> <dt><code>(cl-type <var>type</var>)</code></dt> <dd>
<p>Matches if <var>expval</var> is of type <var>type</var>, which is a type descriptor as accepted by <code>cl-typep</code> (see <a href="https://www.gnu.org/software/emacs/manual/html_node/cl/Type-Predicates.html#Type-Predicates">Type Predicates</a> in <cite>Common Lisp Extensions</cite>). Examples: </p> <div class="lisp"> <pre class="lisp">(cl-type integer)
(cl-type (integer 0 10))
</pre>
</div> </dd> <dt><code>(pred <var>function</var>)</code></dt> <dd>
<p>Matches if the predicate <var>function</var> returns non-<code>nil</code> when called on <var>expval</var>. The test can be negated with the syntax <code>(pred (not <var>function</var>))</code>. The predicate <var>function</var> can have one of the following forms: </p> <dl compact> <dt>function name (a symbol)</dt> <dd>
<p>Call the named function with one argument, <var>expval</var>. </p> <p>Example: <code>integerp</code> </p> </dd> <dt>lambda expression</dt> <dd>
<p>Call the anonymous function with one argument, <var>expval</var> (see <a href="lambda-expressions">Lambda Expressions</a>). </p> <p>Example: <code>(lambda (n) (= 42 n))</code> </p> </dd> <dt>function call with <var>n</var> args</dt> <dd>
<p>Call the function (the first element of the function call) with <var>n</var> arguments (the other elements) and an additional <var>n</var>+1-th argument that is <var>expval</var>. </p> <p>Example: <code>(= 42)</code> In this example, the function is <code>=</code>, <var>n</var> is one, and the actual function call becomes: <code>(= 42 <var>expval</var>)</code>. </p>
</dd> </dl> </dd> <dt><code>(app <var>function</var> <var>pattern</var>)</code></dt> <dd>
<p>Matches if <var>function</var> called on <var>expval</var> returns a value that matches <var>pattern</var>. <var>function</var> can take one of the forms described for <code>pred</code>, above. Unlike <code>pred</code>, however, <code>app</code> tests the result against <var>pattern</var>, rather than against a boolean truth value. </p> </dd> <dt><code>(guard <var>boolean-expression</var>)</code></dt> <dd>
<p>Matches if <var>boolean-expression</var> evaluates to non-<code>nil</code>. </p> </dd> <dt><code>(let <var>pattern</var> <var>expr</var>)</code></dt> <dd><p>Evaluates <var>expr</var> to get <var>exprval</var> and matches if <var>exprval</var> matches <var>pattern</var>. (It is called <code>let</code> because <var>pattern</var> can bind symbols to values using <var>symbol</var>.) </p></dd> </dl> <p>A <em>sequencing pattern</em> (also known as <var>seqpat</var>) is a pattern that processes its sub-pattern arguments in sequence. There are two for <code>pcase</code>: <code>and</code> and <code>or</code>. They behave in a similar manner to the special forms that share their name (see <a href="combining-conditions">Combining Conditions</a>), but instead of processing values, they process sub-patterns. </p> <dl compact> <dt><code>(and <var>pattern1</var>…)</code></dt> <dd>
<p>Attempts to match <var>pattern1</var>…, in order, until one of them fails to match. In that case, <code>and</code> likewise fails to match, and the rest of the sub-patterns are not tested. If all sub-patterns match, <code>and</code> matches. </p> </dd> <dt><code>(or <var>pattern1</var> <var>pattern2</var>…)</code></dt> <dd>
<p>Attempts to match <var>pattern1</var>, <var>pattern2</var>, …, in order, until one of them succeeds. In that case, <code>or</code> likewise matches, and the rest of the sub-patterns are not tested. </p> <p>To present a consistent environment (see <a href="intro-eval">Intro Eval</a>) to <var>body-forms</var> (thus avoiding an evaluation error on match), the set of variables bound by the pattern is the union of the variables bound by each sub-pattern. If a variable is not bound by the sub-pattern that matched, then it is bound to <code>nil</code>. </p>
</dd> <dt><code>(rx <var>rx-expr</var>…)</code></dt> <dd>
<p>Matches strings against the regexp <var>rx-expr</var>…, using the <code>rx</code> regexp notation (see <a href="rx-notation">Rx Notation</a>), as if by <code>string-match</code>. </p> <p>In addition to the usual <code>rx</code> syntax, <var>rx-expr</var>… can contain the following constructs: </p> <dl compact> <dt><code>(let <var>ref</var> <var>rx-expr</var>…)</code></dt> <dd>
<p>Bind the symbol <var>ref</var> to a submatch that matches <var>rx-expr</var><small class="enddots">...</small>. <var>ref</var> is bound in <var>body-forms</var> to the string of the submatch or nil, but can also be used in <code>backref</code>. </p> </dd> <dt><code>(backref <var>ref</var>)</code></dt> <dd><p>Like the standard <code>backref</code> construct, but <var>ref</var> can here also be a name introduced by a previous <code>(let <var>ref</var> …)</code> construct. </p></dd> </dl> </dd> </dl> <h4 class="subheading">Example: Advantage Over <code>cl-case</code>
</h4> <p>Here’s an example that highlights some advantages <code>pcase</code> has over <code>cl-case</code> (see <a href="https://www.gnu.org/software/emacs/manual/html_node/cl/Conditionals.html#Conditionals">Conditionals</a> in <cite>Common Lisp Extensions</cite>). </p> <div class="example"> <pre class="example">(pcase (get-return-code x)
;; string
((and (pred stringp) msg)
(message "%s" msg))
</pre>
<pre class="example"> ;; symbol
('success (message "Done!"))
('would-block (message "Sorry, can't do it now"))
('read-only (message "The shmliblick is read-only"))
('access-denied (message "You do not have the needed rights"))
</pre>
<pre class="example"> ;; default
(code (message "Unknown return code %S" code)))
</pre>
</div> <p>With <code>cl-case</code>, you would need to explicitly declare a local variable <code>code</code> to hold the return value of <code>get-return-code</code>. Also <code>cl-case</code> is difficult to use with strings because it uses <code>eql</code> for comparison. </p> <h4 class="subheading">Example: Using <code>and</code>
</h4> <p>A common idiom is to write a pattern starting with <code>and</code>, with one or more <var>symbol</var> sub-patterns providing bindings to the sub-patterns that follow (as well as to the body forms). For example, the following pattern matches single-digit integers. </p> <div class="example"> <pre class="example">(and
(pred integerp)
n ; <span class="roman">bind <code>n</code> to <var>expval</var></span>
(guard (<= -9 n 9)))
</pre>
</div> <p>First, <code>pred</code> matches if <code>(integerp <var>expval</var>)</code> evaluates to non-<code>nil</code>. Next, <code>n</code> is a <var>symbol</var> pattern that matches anything and binds <code>n</code> to <var>expval</var>. Lastly, <code>guard</code> matches if the boolean expression <code>(<= <span class="nolinebreak">-9</span> n 9)</code> (note the reference to <code>n</code>) evaluates to non-<code>nil</code>. If all these sub-patterns match, <code>and</code> matches. </p> <h4 class="subheading">Example: Reformulation with <code>pcase</code>
</h4> <p>Here is another example that shows how to reformulate a simple matching task from its traditional implementation (function <code>grok/traditional</code>) to one using <code>pcase</code> (function <code>grok/pcase</code>). The docstring for both these functions is: “If OBJ is a string of the form "key:NUMBER", return NUMBER (a string). Otherwise, return the list ("149" default).” First, the traditional implementation (see <a href="regular-expressions">Regular Expressions</a>): </p> <div class="example"> <pre class="example">(defun grok/traditional (obj)
(if (and (stringp obj)
(string-match "^key:\\([[:digit:]]+\\)$" obj))
(match-string 1 obj)
(list "149" 'default)))
</pre>
<pre class="example">(grok/traditional "key:0") ⇒ "0"
(grok/traditional "key:149") ⇒ "149"
(grok/traditional 'monolith) ⇒ ("149" default)
</pre>
</div> <p>The reformulation demonstrates <var>symbol</var> binding as well as <code>or</code>, <code>and</code>, <code>pred</code>, <code>app</code> and <code>let</code>. </p> <div class="example"> <pre class="example">(defun grok/pcase (obj)
(pcase obj
((or ; <span class="roman">line 1</span>
(and ; <span class="roman">line 2</span>
(pred stringp) ; <span class="roman">line 3</span>
(pred (string-match ; <span class="roman">line 4</span>
"^key:\\([[:digit:]]+\\)$")) ; <span class="roman">line 5</span>
(app (match-string 1) ; <span class="roman">line 6</span>
val)) ; <span class="roman">line 7</span>
(let val (list "149" 'default))) ; <span class="roman">line 8</span>
val))) ; <span class="roman">line 9</span>
</pre>
<pre class="example">(grok/pcase "key:0") ⇒ "0"
(grok/pcase "key:149") ⇒ "149"
(grok/pcase 'monolith) ⇒ ("149" default)
</pre>
</div> <p>The bulk of <code>grok/pcase</code> is a single clause of a <code>pcase</code> form, the pattern on lines 1-8, the (single) body form on line 9. The pattern is <code>or</code>, which tries to match in turn its argument sub-patterns, first <code>and</code> (lines 2-7), then <code>let</code> (line 8), until one of them succeeds. </p> <p>As in the previous example (see <a href="#pcase_002dexample_002d1">Example 1</a>), <code>and</code> begins with a <code>pred</code> sub-pattern to ensure the following sub-patterns work with an object of the correct type (string, in this case). If <code>(stringp <var>expval</var>)</code> returns <code>nil</code>, <code>pred</code> fails, and thus <code>and</code> fails, too. </p> <p>The next <code>pred</code> (lines 4-5) evaluates <code><span class="nolinebreak">(string-match</span> RX <var>expval</var>)</code> and matches if the result is non-<code>nil</code>, which means that <var>expval</var> has the desired form: <code>key:NUMBER</code>. Again, failing this, <code>pred</code> fails and <code>and</code>, too. </p> <p>Lastly (in this series of <code>and</code> sub-patterns), <code>app</code> evaluates <code><span class="nolinebreak">(match-string</span> 1 <var>expval</var>)</code> (line 6) to get a temporary value <var>tmp</var> (i.e., the “NUMBER” substring) and tries to match <var>tmp</var> against pattern <code>val</code> (line 7). Since that is a <var>symbol</var> pattern, it matches unconditionally and additionally binds <code>val</code> to <var>tmp</var>. </p> <p>Now that <code>app</code> has matched, all <code>and</code> sub-patterns have matched, and so <code>and</code> matches. Likewise, once <code>and</code> has matched, <code>or</code> matches and does not proceed to try sub-pattern <code>let</code> (line 8). </p> <p>Let’s consider the situation where <code>obj</code> is not a string, or it is a string but has the wrong form. In this case, one of the <code>pred</code> (lines 3-5) fails to match, thus <code>and</code> (line 2) fails to match, thus <code>or</code> (line 1) proceeds to try sub-pattern <code>let</code> (line 8). </p> <p>First, <code>let</code> evaluates <code>(list "149" 'default)</code> to get <code>("149" default)</code>, the <var>exprval</var>, and then tries to match <var>exprval</var> against pattern <code>val</code>. Since that is a <var>symbol</var> pattern, it matches unconditionally and additionally binds <code>val</code> to <var>exprval</var>. Now that <code>let</code> has matched, <code>or</code> matches. </p> <p>Note how both <code>and</code> and <code>let</code> sub-patterns finish in the same way: by trying (always successfully) to match against the <var>symbol</var> pattern <code>val</code>, in the process binding <code>val</code>. Thus, <code>or</code> always matches and control always passes to the body form (line 9). Because that is the last body form in a successfully matched <code>pcase</code> clause, it is the value of <code>pcase</code> and likewise the return value of <code>grok/pcase</code> (see <a href="what-is-a-function">What Is a Function</a>). </p> <h4 class="subheading">Caveats for <var>symbol</var> in Sequencing Patterns</h4> <p>The preceding examples all use sequencing patterns which include the <var>symbol</var> sub-pattern in some way. Here are some important details about that usage. </p> <ol> <li> When <var>symbol</var> occurs more than once in <var>seqpat</var>, the second and subsequent occurrences do not expand to re-binding, but instead expand to an equality test using <code>eq</code>. <p>The following example features a <code>pcase</code> form with two clauses and two <var>seqpat</var>, A and B. Both A and B first check that <var>expval</var> is a pair (using <code>pred</code>), and then bind symbols to the <code>car</code> and <code>cdr</code> of <var>expval</var> (using one <code>app</code> each). </p> <p>For A, because symbol <code>st</code> is mentioned twice, the second mention becomes an equality test using <code>eq</code>. On the other hand, B uses two separate symbols, <code>s1</code> and <code>s2</code>, both of which become independent bindings. </p> <div class="example"> <pre class="example">(defun grok (object)
(pcase object
((and (pred consp) ; seqpat A
(app car st) ; first mention: st
(app cdr st)) ; second mention: st
(list 'eq st))
</pre>
<pre class="example"> ((and (pred consp) ; seqpat B
(app car s1) ; first mention: s1
(app cdr s2)) ; first mention: s2
(list 'not-eq s1 s2))))
</pre>
<pre class="example">(let ((s "yow!"))
(grok (cons s s))) ⇒ (eq "yow!")
(grok (cons "yo!" "yo!")) ⇒ (not-eq "yo!" "yo!")
(grok '(4 2)) ⇒ (not-eq 4 (2))
</pre>
</div> </li>
<li> Side-effecting code referencing <var>symbol</var> is undefined. Avoid. For example, here are two similar functions. Both use <code>and</code>, <var>symbol</var> and <code>guard</code>: <div class="example"> <pre class="example">(defun square-double-digit-p/CLEAN (integer)
(pcase (* integer integer)
((and n (guard (< 9 n 100))) (list 'yes n))
(sorry (list 'no sorry))))
(square-double-digit-p/CLEAN 9) ⇒ (yes 81)
(square-double-digit-p/CLEAN 3) ⇒ (no 9)
</pre>
<pre class="example">(defun square-double-digit-p/MAYBE (integer)
(pcase (* integer integer)
((and n (guard (< 9 (incf n) 100))) (list 'yes n))
(sorry (list 'no sorry))))
(square-double-digit-p/MAYBE 9) ⇒ (yes 81)
(square-double-digit-p/MAYBE 3) ⇒ (yes 9) ; <span class="roman">WRONG!</span>
</pre>
</div> <p>The difference is in <var>boolean-expression</var> in <code>guard</code>: <code>CLEAN</code> references <code>n</code> simply and directly, while <code>MAYBE</code> references <code>n</code> with a side-effect, in the expression <code>(incf n)</code>. When <code>integer</code> is 3, here’s what happens: </p> <ul> <li> The first <code>n</code> binds it to <var>expval</var>, i.e., the result of evaluating <code>(* 3 3)</code>, or 9. </li>
<li> <var>boolean-expression</var> is evaluated: <div class="example"> <pre class="example">start: (< 9 (incf n) 100)
becomes: (< 9 (setq n (1+ n)) 100)
becomes: (< 9 (setq n (1+ 9)) 100)
</pre>
<pre class="example">becomes: (< 9 (setq n 10) 100)
; <span class="roman">side-effect here!</span>
becomes: (< 9 n 100) ; <span class="roman"><code>n</code> now bound to 10</span>
becomes: (< 9 10 100)
becomes: t
</pre>
</div> </li>
<li> Because the result of the evaluation is non-<code>nil</code>, <code>guard</code> matches, <code>and</code> matches, and control passes to that clause’s body forms. </li>
</ul> <p>Aside from the mathematical incorrectness of asserting that 9 is a double-digit integer, there is another problem with <code>MAYBE</code>. The body form references <code>n</code> once more, yet we do not see the updated value—10—at all. What happened to it? </p> <p>To sum up, it’s best to avoid side-effecting references to <var>symbol</var> patterns entirely, not only in <var>boolean-expression</var> (in <code>guard</code>), but also in <var>expr</var> (in <code>let</code>) and <var>function</var> (in <code>pred</code> and <code>app</code>). </p> </li>
<li> On match, the clause’s body forms can reference the set of symbols the pattern let-binds. When <var>seqpat</var> is <code>and</code>, this set is the union of all the symbols each of its sub-patterns let-binds. This makes sense because, for <code>and</code> to match, all the sub-patterns must match. <p>When <var>seqpat</var> is <code>or</code>, things are different: <code>or</code> matches at the first sub-pattern that matches; the rest of the sub-patterns are ignored. It makes no sense for each sub-pattern to let-bind a different set of symbols because the body forms have no way to distinguish which sub-pattern matched and choose among the different sets. For example, the following is invalid: </p> <div class="example"> <pre class="example">(require 'cl-lib)
(pcase (read-number "Enter an integer: ")
((or (and (pred cl-evenp)
e-num) ; <span class="roman">bind <code>e-num</code> to <var>expval</var></span>
o-num) ; <span class="roman">bind <code>o-num</code> to <var>expval</var></span>
(list e-num o-num)))
</pre>
<pre class="example">Enter an integer: 42
error→ Symbol’s value as variable is void: o-num
</pre>
<pre class="example">Enter an integer: 149
error→ Symbol’s value as variable is void: e-num
</pre>
</div> <p>Evaluating body form <code>(list <span class="nolinebreak">e-num</span> <span class="nolinebreak">o-num)</span></code> signals error. To distinguish between sub-patterns, you can use another symbol, identical in name in all sub-patterns but differing in value. Reworking the above example: </p> <div class="example"> <pre class="example">(require 'cl-lib)
(pcase (read-number "Enter an integer: ")
((and num ; <span class="roman">line 1</span>
(or (and (pred cl-evenp) ; <span class="roman">line 2</span>
(let spin 'even)) ; <span class="roman">line 3</span>
(let spin 'odd))) ; <span class="roman">line 4</span>
(list spin num))) ; <span class="roman">line 5</span>
</pre>
<pre class="example">Enter an integer: 42
⇒ (even 42)
</pre>
<pre class="example">Enter an integer: 149
⇒ (odd 149)
</pre>
</div> <p>Line 1 “factors out” the <var>expval</var> binding with <code>and</code> and <var>symbol</var> (in this case, <code>num</code>). On line 2, <code>or</code> begins in the same way as before, but instead of binding different symbols, uses <code>let</code> twice (lines 3-4) to bind the same symbol <code>spin</code> in both sub-patterns. The value of <code>spin</code> distinguishes the sub-patterns. The body form references both symbols (line 5). </p>
</li>
</ol><div class="_attribution">
<p class="_attribution-p">
Copyright © 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/pcase-Macro.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/pcase-Macro.html</a>
</p>
</div>
|