New page on the Cookbook: https://lispcookbook.github.io/cl-cookbook/pattern_matching.html All examples come from Trivia’s wiki.
The ANSI Common Lisp standard does not include facilities for pattern matching, but libraries existed for this task and Trivia became a community standard.
Table of Contents
- Common destructuring patterns
For an introduction to the concepts of pattern matching, see Trivia’s wiki.
Trivia matches against a lot of lisp objects and is extensible.
The library is in Quicklisp:
For the following examples, let’s
use the library:
Common destructuring patterns
(match '(1 2 3) ((cons x y) ; ^^ pattern (print x) (print y))) ;; |-> 1 ;; |-> (2 3)
(match '(something #(0 1 2)) ((list a (vector 0 _ b)) (values a b))) SOMETHING 2
(match '(1 2 . 3) ((list* _ _ x) x)) 3
Note that using
list would match nothing.
vector checks if the object is a vector, if the lengths are the
same, and if the contents matches against each subpatterns.
vector* is similar, but called a soft-match variant that allows if
the length is larger-than-equal to the length of subpatterns.
(match #(1 2 3) ((vector _ x _) x)) ;; -> 2
(match #(1 2 3 4) ((vector _ x _) x)) ;; -> NIL : does not match
(match #(1 2 3 4) ((vector* _ x _) x)) ;; -> 2 : soft match.
<vector-pattern> : vector | simple-vector bit-vector | simple-bit-vector string | simple-string base-string | simple-base-string | sequence (<vector-pattern> &rest subpatterns)
Class and structure pattern
There are three styles that are equivalent:
(defstruct foo bar baz) (defvar *x* (make-foo :bar 0 :baz 1) (match *x* ;; make-instance style ((foo :bar a :baz b) (values a b)) ;; with-slots style ((foo (bar a) (baz b)) (values a b)) ;; slot name style ((foo bar baz) (values bar baz)))
type pattern matches if the object is of type.
if the predicate returns true for the object. A lambda form is
All these patterns first check if the pattern is a list. If that is satisfied, then they obtain the contents, and the value is matched against the subpattern.
Array, simple-array, row-major-array patterns
Logic based patterns
(match x ((or (list 1 a) (cons a 3)) a))
matches against both
(1 2) and
(4 . 3) and returns 2 and 4, respectively.
It does not match when subpattern matches. The variables used in the subpattern are not visible in the body.
The syntax is
a test form, and the body.
(match (list 2 5) ((guard (list x y) ; subpattern (= 10 (* x y)) ; test-form (- x y) (satisfies evenp)) ; generator1, subpattern1 t))
If the subpattern is true, the test form is evaluated, and if it is true it is matched against subpattern1.
The above returns
(- x y) == 3 does not satisfies
Patterns can be nested:
(match '(:a (3 4) 5) ((list :a (list _ c) _) c))
See special patterns: