cond form lets you choose between alternatives using
predicate conditions that compare values of expressions against
specific values known and written in advance. However, sometimes it
is useful to select alternatives based on more general conditions that
distinguish between broad classes of values. The
allows you to choose between alternatives based on matching the value
of an expression against a series of patterns. A pattern can be a
literal value (for comparisons to literal values you’d use
cond), or it can be a more general description of the expected
structure of the expression’s value.
Evaluate expression and choose among an arbitrary number of
alternatives based on the value of expression. The possible
alternatives are specified by clauses, each of which must be a
list of the form
pcase tries to match the value of expression to the
pattern of each clause, in textual order. If the value matches,
the clause succeeds;
pcase then evaluates its body-forms,
and returns the value of the last of body-forms. Any remaining
clauses are ignored.
The pattern part of a clause can be of one of two types: QPattern, a pattern quoted with a backquote; or a UPattern, which is not quoted. UPatterns are simpler, so we describe them first.
Note: In the description of the patterns below, we use “the value
being matched” to refer to the value of the expression that is
the first argument of
A UPattern can have the following forms:
Matches if the value being matched is
equal to val.
Matches any atom, which can be a keyword, a number, or a string.
(These are self-quoting, so this kind of UPattern is actually a
'atom.) Note that a string or a float
matches any string or float with the same contents/value.
Matches any value. This is known as don’t care or wildcard.
Matches any value, and additionally let-binds symbol to the value it matched, so that you can later refer to it, either in the body-forms or also later in the pattern.
Matches if the predicate function predfun returns non-
when called with the value being matched as its argument.
predfun can be one of the possible forms described below.
Matches if boolean-expression evaluates to non-
allows you to include in a UPattern boolean conditions that refer to
symbols bound to values (including the value being matched) by
previous UPatterns. Typically used inside an
and UPattern, see
below. For example,
(and x (guard (< x 10))) is a pattern
which matches any number smaller than 10 and let-binds the variable
x to that number.
(let upattern expression)
Matches if the specified expression matches the specified
upattern. This allows matching a pattern against the value of
an arbitrary expression, not just the expression that is the
first argument to
pcase. (It is called
upattern can bind symbols to values using the symbol
UPattern. For example:
((or `(key . ,val) (let val 5)) val).)
(app function upattern)
Matches if function applied to the value being matched returns a
value that matches upattern. This is like the
UPattern, except that it tests the result against UPattern,
rather than against a boolean truth value. The function call can
use one of the forms described below.
(or upattern1 upattern2…)
Matches if one the argument UPatterns matches. As soon as the first matching UPattern is found, the rest are not tested. For this reason, if any of the UPatterns let-bind symbols to the matched value, they should all bind the same symbols.
(and upattern1 upattern2…)
Matches if all the argument UPatterns match.
The function calls used in the
can have one of the following forms:
In this case, the named function is applied to the value being matched.
(lambda (arg) body)
In this case, the lambda-function is called with one argument, the value being matched.
This is a function call with n specified arguments; the function is called with these n arguments and an additional n+1-th argument that is the value being matched.
Here’s an illustrative example of using UPatterns:
(pcase (get-return-code x) ('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")) (code (message "Unknown return code %S" code)))
In addition, you can use backquoted patterns that are more powerful.
They allow matching the value of the expression that is the
first argument of
pcase against specifications of its
structure. For example, you can specify that the value must be
a list of 2 elements whose first element is a specific string and the
second element is any value with a backquoted pattern like
Backquoted patterns have the form
qpattern can have the following forms:
(qpattern1 . qpattern2)
Matches if the value being matched is a cons cell whose
matches qpattern1 and whose
cdr matches qpattern2.
This readily generalizes to backquoted lists as in
(qpattern1 qpattern2 …).
[qpattern1 qpattern2 … qpatternm]
Matches if the value being matched is a vector of length m whose
(m-1)th elements match qpattern1,
qpattern2 … qpatternm, respectively.
Matches if corresponding element of the value being matched is
equal to the specified atom.
Matches if the corresponding element of the value being matched matches the specified upattern.
Note that uses of QPatterns can be expressed using only UPatterns, as
QPatterns are implemented on top of UPatterns using
pcase-defmacro, described below. However, using QPatterns will
in many cases lead to a more readable code.
Here is an example of using
pcase to implement a simple
interpreter for a little expression language (note that this example
requires lexical binding, see Lexical Binding):
(defun evaluate (exp env) (pcase exp (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) (`(call ,fun ,arg) (funcall (evaluate fun env) (evaluate arg env))) (`(fn ,arg ,body) (lambda (val) (evaluate body (cons (cons arg val) env)))) ((pred numberp) exp) ((pred symbolp) (cdr (assq exp env))) (_ (error "Unknown expression %S" exp))))
`(add ,x ,y) is a pattern that checks that
exp is a
three-element list starting with the literal symbol
extracts the second and third elements and binds them to the variables
y. Then it evaluates
adds the results. The
fn patterns similarly
implement two flavors of function calls.
(pred numberp) is a
pattern that simply checks that
exp is a number and if so,
(pred symbolp) matches symbols, and returns
their association. Finally,
_ is the catch-all pattern that
matches anything, so it’s suitable for reporting syntax errors.
Here are some sample programs in this small language, including their evaluation results:
(evaluate '(add 1 2) nil) ;=> 3 (evaluate '(add x y) '((x . 1) (y . 2))) ;=> 3 (evaluate '(call (fn x (add 1 x)) 2) nil) ;=> 3 (evaluate '(sub 1 2) nil) ;=> error
Additional UPatterns can be defined using the
Define a new kind of UPattern for
pcase. The new UPattern will
be invoked as
(name actual-args). The body
should describe how to rewrite the UPattern name into some other
UPattern. The rewriting will be the result of evaluating body
in an environment where args are bound to actual-args.