User-definable pattern-matching.
Examples:
(pattern-match x ((cons a b) ... body1 ... ) ((three-elt-constructor a & c) ... body2 ...) (& default-value))
Pattern-match is similar to case-match, but the two macros interpret
patterns differently. If the pattern is
(pattern-match input (pattern1 declare-form condition11 condition12 ... declare-form body1) (pattern2 condition21 condition22 ... body2) ...)
In the previous invocation, pattern-match first matches the input to
pattern1. If it matches, condition11, condition12, ... are evaluated using any
variable bindings that pattern1 created, and using the declare form preceding
them if there is one. (The declare form is primarily useful for declaring
ignored variables.) If they all evaluate to non-nil, body1 is evaluated and
returned with the same variable bindings and with the declare form preceding
it, if any. If pattern1 does not match or any of the conditions evaluate to
nil, body1 is not evaluated and pattern2 is tried, and so on. The list of
patterns should be comprehensive or else end with a listing of the form
In each pattern clause the declare forms and conditions are optional. Conditions may be included without declare forms and vice versa. To distinguish declare forms from conditions we simply check whether the first item following the pattern and/or the last item before the body are declare forms; everything between the pattern and body that is not a declare form is assumed to be a condition.
Each pattern may be a variable, to be bound to the value of the input; an
existing variable name prefixed by ! or a constant, the value of which is to be
compared with the input value; the special symbol
The pattern-match book includes built-in support for the constructors
For example, the following pattern-match statement returns
(pattern-match (list 1 (cons 1 (cons 2 3))) ((cons a (bind k (raw ((a b . c))))) (list a k)))
For documentation on enabling pattern-match to recognize new constructors, see def-pattern-match-constructor and for more see constructor-pattern-match-macros.
Note 1: Currently pattern-match does not bind the input expression to an internal variable, but simply copies it everywhere it is used. Therefore it is wise, if the input is from some expensive calculation, to bind it to a variable before applying pattern-match.
Note 2: The default value of a pattern-match expression in case no patterns
match is nil. Because of this, if the pattern-match expression is supposed to
evaluate to a special shape (an mv, or state, for instance), a default value of
the correct shape must be defined by including a final clause of the form