cond* macro ¶You can use the cond* macro as an alternative to pcase
if you find pcase’s syntax too cryptic. In addition,
cond* offers some new forms of control flow that aren’t related
to being an alternative to pcase.
The cond* macro is an extended form of the traditional
cond. A cond* expression contains a series of
clauses, each of which can use bind* or bind-and* to
specify binding variables, use match* or pcase* to specify
matching a pattern as a condition, or specify an expression as a
condition to evaluate as a test.
Each clause normally has the form (condition body…).
condition can be a Lisp expression, as in cond
(see Conditionals). Or it can be (bind* bindings…), (match* pattern datum),
(bind-and* bindings…) or (pcase* pattern datum)
(bind* bindings…) means to bind bindings (like
the bindings list in let*, see Local Variables) for the body
of the clause, and all subsequent clauses. As a condition, it counts as
true if the first binding’s value is non-nil.
(bind-and* bindings…) means to bind bindings
(like the bindings list in if-let*, see Conditionals) for
only the body of the clause. As a condition, it counts as true if none
of the bindings evaluate to nil. In addition, if any binding
evaluates to nil, the expressions for the values of subsequent
bindings are not evaluated.
(match* pattern datum) means to match datum
against the specified pattern. The condition counts as true if
pattern matches datum. The pattern can specify variables to
bind to the parts of datum that they match.
(pcase* pattern datum) works in the same way except it
uses the Pcase syntax for pattern.
match*, and pcase* normally bind their bindings over the
execution of the whole containing clause. However, if the clause is
written to specify “non-exit” (see below), the clause’s bindings cover
the whole rest of the cond*.
When a clause’s condition is true, and it exits the cond* or is
the last clause, the value of the last expression in the clause’s body
becomes the return value of the cond* construct.
If the first element of a clause is t or a bind* form, or
if it has only one element and that element is a match* or
pcase* form, or if it ends with the keyword :non-exit,
then this clause never exits the cond* construct. Instead,
control falls through to the next clause (if any). Except for a
bind-and* clause, the bindings made in condition for the
body of the non-exit clause are passed along to the rest of the
clauses in this cond* construct.
Note: pcase* does not support :non-exit, and when used in
a non-exit clause, it follows the semantics of pcase-let, see
Destructuring with pcase Patterns.
A matching clause looks like (match* pattern datum).
It evaluates the expression datum and matches the pattern
pattern (which is not evaluated) against it.
pattern allows these kinds of patterns, and those that are lists often include other patterns within them:
_Matches any value.
keywordMatches that keyword.
nilMatches nil.
tMatches t.
symbolMatches any value and binds symbol to that value. If symbol has been matched and bound earlier in this pattern, it matches here the same value that it matched before.
regexpMatches a string if regexp matches it. The match must cover the entire string from its first char to its last.
atom(Meaning any other kind of non-list not described above.) Matches anything ‘equal’ to it.
(rx regexp)Uses a regexp specified in s-expression form, as in the function
rx (see The rx Structured Regexp Notation, and matches the data that way.
(rx regexp sym0 sym1…)Uses a regexp specified in s-expression form, and binds the symbols
sym0, sym1, and so on to (match-string 0 datum), (match-string 1 datum), and so on. You
can use as many syms as regexp matching supports.
`objectMatches any value equal to object.
(cons carpat cdrpat)Matches a cons cell if carpat matches its car and
cdrpat matches its cdr.
(list eltpats…)Matches a list if the eltpats match its elements. The first eltpat should match the list’s first element. The second eltpat should match the list’s second element. And so on.
(vector eltpats…)Matches a vector if the eltpats match its elements. The first eltpat should match the vector’s first element. The second eltpat should match the vector’s second element. And so on.
(cdr pattern)Matches pattern with strict checking of cdrs. That means
that list patterns verify that the final cdr is
nil. Strict checking is the default.
(cdr-ignore pattern)Matches pattern with lax checking of cdrs. That means that
list patterns do not examine the final cdr.
(and conjuncts…)Matches each of the conjuncts against the same data. If all of them match, this pattern succeeds. If one conjunct fails, this pattern fails and does not try more conjuncts.
(or disjuncts…)Matches each of the disjuncts against the same data. If one disjunct succeeds, this pattern succeeds and does not try more disjuncts. If all of them fail, this pattern fails.
(cond*-expander …)Here the car is a symbol that has a cond*-expander
property which defines how to handle it in a pattern. The property
value is a function. Trying to match such a pattern calls that function
with one argument, the pattern in question (including its car).
The function should return an equivalent pattern to be matched instead.
(predicate symbol)Matches datum if (predicate datum) is true, then
binds symbol to datum.
(predicate SYMBOL more-args…)Matches datum if (predicate datum more-args…) is true, then binds symbol to
datum. more-args… can refer to symbols bound earlier
in the pattern.
(constrain symbol exp)Matches datum if the form exp is true. exp can refer to symbols bound earlier in the pattern.