A simple pattern matcher that allows you to bind parts of matched expressions to variables.
The current version uses continuation-passing style to scan patterns, which can be tail-call optimized by many Common Lisp implementations. I find it hard to imagine anyone’s patterns becoming so deeply nested or long that the nested calls used to scan them becomes a problem, in any case.
(match expr &rest clauses)
Do simple pattern matching on EXPR
, binding any symbols in the
patterns in CLAUSES
for their respective bodies. Each clause has
the form (pattern guard-expr &rest body)
or (pattern expr)
.
MATCH
works similarly to COND
: clauses are tried in sequential
order, and the first matching pattern decides which clause executes
and returns a value. If no patterns are matched, NIL
is returned.
A single underscore can be used in patterns to indicate that the value in that position is ignored. Multiple underscores may be used to ignore multiple values.
Currently only elements of lists may be matched for binding. All
other data is compared with EQ
.
This may be useful as a default clause. Any clauses after this one will never execute.
(match foo
(x (format t "~A" x))) ; x is bound to the value of foo
In this example, FOO
must be a list containing 0, 1, 2, some value,
and the keyword :BAR
. X
is bound to the unspecified value.
(match foo
((0 1 2 x :bar) x))
Match any four element list with a third value that is a number,
binding the value of the third element to X
.
(match foo
((_ _ x _) (numberp x) x))
(defun foldr (f z xs)
(match xs
(() z)
((x . xs) (funcall f x (foldr f z xs)))))
(defun foldl (f z xs)
(match xs
(() z)
((x . xs) (foldl f (funcall f z x) xs))))