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
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:
(ql:quickload "trivia")
For the following examples, let’s use
the library:
(use-package :trivia)
Common destructuring patterns
cons
(match '(1 2 3)
((cons x y)
; ^^ pattern
(print x)
(print y)))
;; |-> 1
;; |-> (2 3)
list
, list*
(match '(something #(0 1 2))
((list a (vector 0 _ b))
(values a b)))
SOMETHING
2
list*
pattern:
(match '(1 2 . 3)
((list* _ _ x)
x))
3
Note that using list
would match nothing.
vector
, vector*
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
, satisfies
The type
pattern matches if the object is of type. satisfies
matches
if the predicate returns true for the object. A lambda form is
acceptable.
assoc
, property
, alist
, plist
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
and
, or
(match x
((or (list 1 a)
(cons a 3))
a))
matches against both (1 2)
and (4 . 3)
and returns 2 and 4, respectively.
not
It does not match when subpattern matches. The variables used in the subpattern are not visible in the body.
guards
The syntax is guard
+ subpattern
+ 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 nil
, since (- x y) == 3
does not satisfies evenp
.
Nesting patterns
Patterns can be nested:
(match '(:a (3 4) 5)
((list :a (list _ c) _)
c))
returns 4
.
See more
See special patterns: place
, bind
and access
.