For background, See Pattern-Matching Conditional.
Each clause in clauses has the form:
Evaluate expression to determine its value, expval. Find the first clause in clauses whose pattern matches expval and pass control to that clause’s body-forms.
If there is a match, the value of
pcase is the value
of the last of body-forms in the successful clause.
pcase evaluates to
Each pattern has to be a pcase pattern, which can use
either one of the core patterns defined below, or one of the patterns
pcase-defmacro (see Extending
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:
Matches any expval. This is also known as don’t care or wildcard.
Matches if expval equals val. The comparison is done as
equal (see Equality Predicates).
Matches if expval equals the literal object.
This is a special case of
possible because literal objects of these types are self-quoting.
Matches any expval, and additionally let-binds symbol to expval, such that this binding is available to body-forms (see Dynamic Binding).
If symbol is part of a sequencing pattern seqpat
(e.g., by using
and, below), the binding is also available to
the portion of seqpat following the appearance of symbol.
This usage has some caveats, see caveats.
Two symbols to avoid are
t, which behaves like
(above) and is deprecated, and
nil, which signals an error.
Likewise, it makes no sense to bind keyword symbols
(see Variables that Never Change).
Matches if expval is of type type, which is a type
descriptor as accepted by
cl-typep (see Type Predicates in Common
Lisp Extensions). Examples:
(cl-type integer) (cl-type (integer 0 10))
Matches if the predicate function returns non-
when called on expval. The test can be negated with the syntax
(pred (not function)).
The predicate function can have one of the following forms:
Call the named function with one argument, expval.
Call the anonymous function with one argument, expval (see Lambda Expressions).
(lambda (n) (= 42 n))
Call the function (the first element of the function call) with n arguments (the other elements) and an additional n+1-th argument that is expval.
In this example, the function is
=, n is one, and
the actual function call becomes:
(= 42 expval).
(app function pattern)
Matches if function called on expval returns a
value that matches pattern.
function can take one of the forms described for
app tests the result
against pattern, rather than against a boolean truth value.
Matches if boolean-expression evaluates to non-
(let pattern expr)
Evaluates expr to get exprval and matches if exprval
matches pattern. (It is called
let because pattern
can bind symbols to values using symbol.)
A sequencing pattern (also known as seqpat) is a
pattern that processes its sub-pattern arguments in sequence.
There are two for
They behave in a similar manner to the special forms
that share their name (see Constructs for Combining Conditions),
but instead of processing values, they process sub-patterns.
Attempts to match pattern1…, in order, until one of them
fails to match. In that case,
and likewise fails to match, and
the rest of the sub-patterns are not tested. If all sub-patterns
(or pattern1 pattern2…)
Attempts to match pattern1, pattern2, …, in order,
until one of them succeeds. In that case,
or likewise matches,
and the rest of the sub-patterns are not tested.
To present a consistent environment
(see Introduction to Evaluation)
to body-forms (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
Matches strings against the regexp rx-expr…, using the
rx regexp notation (see The
rx Structured Regexp Notation), as if by
In addition to the usual
rx syntax, rx-expr… can
contain the following constructs:
(let ref rx-expr…)
Bind the symbol ref to a submatch that matches
rx-expr.... ref is bound in body-forms to
the string of the submatch or
nil, but can also be used in
Like the standard
backref construct, but ref can here
also be a name introduced by a previous
(let ref …)
Here’s an example that highlights some advantages
(see Conditionals in Common Lisp Extensions).
(pcase (get-return-code x) ;; string ((and (pred stringp) msg) (message "%s" msg))
;; 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"))
;; default (code (message "Unknown return code %S" code)))
cl-case, you would need to explicitly declare a local
code to hold the return value of
cl-case is difficult to use with strings because it
eql for comparison.
A common idiom is to write a pattern starting with
with one or more symbol 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.
(and (pred integerp) n ; bind
nto expval (guard (<= -9 n 9)))
pred matches if
evaluates to non-
n is a symbol pattern that matches
anything and binds
n to expval.
guard matches if the boolean expression
(<= -9 n 9) (note the reference to
evaluates to non-
If all these sub-patterns match,
Here is another example that shows how to reformulate a simple
matching task from its traditional implementation
grok/traditional) to one using
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 Regular Expressions):
(defun grok/traditional (obj) (if (and (stringp obj) (string-match "^key:\\([[:digit:]]+\\)$" obj)) (match-string 1 obj) (list "149" 'default)))
(grok/traditional "key:0") ⇒ "0" (grok/traditional "key:149") ⇒ "149" (grok/traditional 'monolith) ⇒ ("149" default)
The reformulation demonstrates symbol binding as well as
(defun grok/pcase (obj) (pcase obj ((or ; line 1 (and ; line 2 (pred stringp) ; line 3 (pred (string-match ; line 4 "^key:\\([[:digit:]]+\\)$")) ; line 5 (app (match-string 1) ; line 6 val)) ; line 7 (let val (list "149" 'default))) ; line 8 val))) ; line 9
(grok/pcase "key:0") ⇒ "0" (grok/pcase "key:149") ⇒ "149" (grok/pcase 'monolith) ⇒ ("149" default)
The bulk of
grok/pcase is a single clause of a
form, the pattern on lines 1-8, the (single) body form on line 9.
The pattern is
or, which tries to match in turn its argument
and (lines 2-7), then
let (line 8),
until one of them succeeds.
As in the previous example (see Example 1),
and begins with a
pred sub-pattern to ensure
the following sub-patterns work with an object of the correct
type (string, in this case). If
pred fails, and thus
and fails, too.
pred (lines 4-5) evaluates
(string-match RX expval)
and matches if the result is non-
nil, which means
that expval has the desired form:
Again, failing this,
pred fails and
Lastly (in this series of
(match-string 1 expval) (line 6)
to get a temporary value tmp (i.e., the “NUMBER” substring)
and tries to match tmp against pattern
val (line 7).
Since that is a symbol pattern, it matches unconditionally
and additionally binds
val to tmp.
app has matched, all
have matched, and so
and has matched,
and does not proceed to try sub-pattern
let (line 8).
Let’s consider the situation where
obj is not a string,
or it is a string but has the wrong form.
In this case, one of the
pred (lines 3-5) fails to match,
and (line 2) fails to match,
or (line 1) proceeds to try sub-pattern
let (line 8).
(list "149" 'default)
("149" default), the exprval, and then
tries to match exprval against pattern
Since that is a symbol pattern, it matches unconditionally
and additionally binds
val to exprval.
let has matched,
Note how both
let sub-patterns finish in the
same way: by trying (always successfully) to match against the
val, in the process binding
or always matches and control always passes
to the body form (line 9).
Because that is the last body form in a successfully matched
pcase clause, it is the value of
pcase and likewise
the return value of
grok/pcase (see What Is a Function?).
The preceding examples all use sequencing patterns which include the symbol sub-pattern in some way. Here are some important details about that usage.
The following example features a
with two clauses and two seqpat, A and B.
Both A and B first check that expval is a
and then bind symbols to the
of expval (using one
For A, because symbol
st is mentioned twice, the second
mention becomes an equality test using
On the other hand, B uses two separate symbols,
s2, both of which become independent bindings.
(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))
((and (pred consp) ; seqpat B (app car s1) ; first mention: s1 (app cdr s2)) ; first mention: s2 (list 'not-eq s1 s2))))
(let ((s "yow!")) (grok (cons s s))) ⇒ (eq "yow!") (grok (cons "yo!" "yo!")) ⇒ (not-eq "yo!" "yo!") (grok '(4 2)) ⇒ (not-eq 4 (2))
and, symbol and
(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)
(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) ; WRONG!
The difference is in boolean-expression in
n simply and directly,
n with a side-effect,
in the expression
integer is 3, here’s what happens:
nbinds it to expval, i.e., the result of evaluating
(* 3 3), or 9.
start: (< 9 (incf n) 100) becomes: (< 9 (setq n (1+ n)) 100) becomes: (< 9 (setq n (1+ 9)) 100)
becomes: (< 9 (setq n 10) 100) ; side-effect here! becomes: (< 9 n 100) ;
nnow bound to 10 becomes: (< 9 10 100) becomes: t
andmatches, and control passes to that clause’s body forms.
Aside from the mathematical incorrectness of asserting that 9 is a
double-digit integer, there is another problem with
The body form references
n once more, yet we do not see
the updated value—10—at all. What happened to it?
To sum up, it’s best to avoid side-effecting references to
symbol patterns entirely, not only
in boolean-expression (in
but also in expr (in
and function (in
and, this set is the union of all the symbols each of its sub-patterns let-binds. This makes sense because, for
andto match, all the sub-patterns must match.
When seqpat is
or, things are different:
or 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:
(require 'cl-lib) (pcase (read-number "Enter an integer: ") ((or (and (pred cl-evenp) e-num) ; bind
e-numto expval o-num) ; bind
o-numto expval (list e-num o-num)))
Enter an integer: 42 error→ Symbol’s value as variable is void: o-num
Enter an integer: 149 error→ Symbol’s value as variable is void: e-num
Evaluating body form
(list e-num o-num) 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:
(require 'cl-lib) (pcase (read-number "Enter an integer: ") ((and num ; line 1 (or (and (pred cl-evenp) ; line 2 (let spin 'even)) ; line 3 (let spin 'odd))) ; line 4 (list spin num))) ; line 5
Enter an integer: 42 ⇒ (even 42)
Enter an integer: 149 ⇒ (odd 149)
Line 1 “factors out” the expval binding with
and and symbol (in this case,
On line 2,
or begins in the same way as before,
but instead of binding different symbols, uses
(lines 3-4) to bind the same symbol
spin in both sub-patterns.
The value of
spin distinguishes the sub-patterns.
The body form references both symbols (line 5).