Up: Conditionals

To compare a particular value against various possible cases, the macro
`pcase`

can come handy. It takes the following form:

(pcaseexpbranch1branch2branch3 ...)

where each `branch` takes the form `(`

`upattern`
`body-forms``...)`

.

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 `(get-return-code x)`

.

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))))

Where ``(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 `x`

and `y`

.
`(pred numberp)`

is a pattern that simply checks that `exp`

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 `pcase`

, called
*U-patterns* and *Q-patterns*. The `upattern` mentioned above
are U-patterns and can take the following forms:

```

`qpattern`- 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 whose`cdr`

matches`PATTERN2`. `atom`- This pattern matches any atom
`equal`

to`atom`. `,`

`upattern`- This pattern matches any object that matches the
`upattern`.

`symbol`- 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. `(pred`

`pred``)`

- This pattern matches if the function
`pred`returns non-`nil`

when 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.
`(guard`

`exp``)`

- This pattern ignores the object being examined and simply succeeds if
`exp`evaluates to non-`nil`

and fails otherwise. It is typically used inside an`and`

pattern. For example,`(and x (guard (< x 10)))`

is a pattern which matches any number smaller than 10 and let-binds it to the variable`x`

.