This subsection describes backquote-style patterns, a set of builtin patterns that eases structural matching. For background, see Pattern-Matching Conditional.
Backquote-style patterns are a powerful set of
extensions (created using
pcase-defmacro) that make it easy to
match expval against specifications of its structure.
For example, to match expval that must be a list of two elements whose first element is a specific string and the second element is any value, you can write a core pattern:
(and (pred listp) ls
(guard (= 2 (length ls))) (guard (string= "first" (car ls))) (let second-elem (cadr ls)))
or you can write the equivalent backquote-style pattern:
The backquote-style pattern is more concise,
resembles the structure of expval,
and avoids binding
A backquote-style pattern has the form
qpat can have the following forms:
(qpat1 . qpat2)
Matches if expval is a cons cell whose
matches qpat1 and whose
cdr matches qpat2.
This readily generalizes to lists as in
(qpat1 qpat2 …).
[qpat1 qpat2 … qpatm]
Matches if expval is a vector of length m whose
(m-1)th elements match qpat1,
qpat2 … qpatm, respectively.
Matches if the corresponding element of expval is
equal to the specified literal object.
Matches if the corresponding element of expval
Note that pattern is any kind that
(In the example above,
second-elem is a symbol
core pattern; it therefore matches anything,
The corresponding element is the portion of expval
that is in the same structural position as the structural position
of qpat in the backquote-style pattern.
(In the example above, the corresponding element of
second-elem is the second element of expval.)
Here is an example of using
pcase to implement a simple
interpreter for a little expression language
(note that this requires lexical binding for the
lambda expression in the
fn clause to properly
arg (see Lexical Binding):
(defun evaluate (form env) (pcase form (`(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) form) ((pred symbolp) (cdr (assq form env))) (_ (error "Syntax error: %S" form))))
The first three clauses use backquote-style patterns.
`(add ,x ,y) is a pattern that checks that
is a three-element list starting with the literal symbol
then extracts the second and third elements and binds them
The clause body evaluates
y and adds the results.
call clause implements a function call,
fn clause implements an anonymous function definition.
The remaining clauses use core patterns.
(pred numberp) matches if
form is a number.
On match, the body evaluates it.
(pred symbolp) matches if
form is a symbol.
On match, the body looks up the symbol in
returns its association.
_ 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