To compare a particular value against various possible cases, the macro
pcase can come handy. It takes the following form:
(pcase exp branch1 branch2 branch3 …)
where each branch takes the form
It will first evaluate exp and then compare the value against each upattern to see which branch to use, after which it will run the corresponding body-forms. A common use case is to distinguish between a few different constant values:
(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 the last clause,
code is a variable that gets bound to the value that
was returned by
To give a more complex example, a simple interpreter for a little expression language could look like (note that this example requires 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 symbol
add, then extracts the second and
third elements and binds them to the variables
(pred numberp) is a pattern that simply checks that
is a number, and
_ is the catch-all pattern that matches anything.
Here are some sample programs 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
There are two kinds of patterns involved in
U-patterns and Q-patterns. The upattern mentioned above
are U-patterns and can take the following forms:
This is one of the most common form of patterns. The intention is to mimic the backquote macro: this pattern matches those values that could have been built by such a backquote expression. Since we’re pattern matching rather than building a value, the unquote does not indicate where to plug an expression, but instead it lets one specify a U-pattern that should match the value at that location.
More specifically, a Q-pattern can take the following forms:
(qpattern1 . qpattern2)
This pattern matches any cons cell whose
car matches qpattern1 and
cdr matches pattern2.
This pattern matches any atom
equal to atom.
This pattern matches any object that matches the upattern.
A mere symbol in a U-pattern matches anything, and additionally let-binds this symbol to the value that it matched, so that you can later refer to it, either in the body-forms or also later in the pattern.
This so-called don’t care pattern matches anything, like the previous one, but unlike symbol patterns it does not bind any variable.
This pattern matches if the function pred returns non-
called with the object being matched.
(or upattern1 upattern2…)
This pattern matches as soon as one of the argument patterns succeeds. All argument patterns should let-bind the same variables.
(and upattern1 upattern2…)
This pattern matches only if all the argument patterns succeed.
This pattern ignores the object being examined and simply succeeds if exp
evaluates to non-
nil and fails otherwise. It is typically used inside
and pattern. For example,
(and x (guard (< x 10)))
is a pattern which matches any number smaller than 10 and let-binds it to