Skip to content

Commit 686fe9f

Browse files
committed
pattern matching: explain a bit more, fix guard example
1 parent d5e2bb8 commit 686fe9f

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

clos.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ The metaclass of a `structure-object` is the class
718718

719719
### Introspection
720720

721-
we already saw some introspection functions.
721+
We already saw some introspection functions.
722722

723723
Your best option is to discover the
724724
[closer-mop](https://github.com/pcostanza/closer-mop) library and to

pattern_matching.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,35 @@ For the following examples, let's `use` the library:
4040

4141
### `list`, `list*`
4242

43+
`list` is a strict pattern, it expects the length of the matched
44+
object to be the same length as its subpatterns.
45+
4346
~~~lisp
44-
(match '(something #(0 1 2))
45-
((list a (vector 0 _ b))
47+
(match '(something 2 3)
48+
((list a b _)
4649
(values a b)))
4750
SOMETHING
4851
2
4952
~~~
5053

51-
`list*` pattern:
54+
Without the `_` placeholder, it would not match:
55+
56+
~~~lisp
57+
(match '(something 2 3)
58+
((list a b)
59+
(values a b)))
60+
NIL
61+
~~~
62+
63+
The `list*` pattern is flexible on the object's length:
64+
65+
~~~lisp
66+
(match '(something 2 3)
67+
((list* a b)
68+
(values a b)))
69+
SOMETHING
70+
(2 3)
71+
~~~
5272

5373
~~~lisp
5474
(match '(1 2 . 3)
@@ -57,7 +77,18 @@ SOMETHING
5777
3
5878
~~~
5979

60-
Note that using `list` would match nothing.
80+
However pay attention that if `list*` receives only one object, that
81+
object is returned, regardless of whether or not it is a list:
82+
83+
~~~lisp
84+
(match #(0 1 2)
85+
((list* a)
86+
a))
87+
#(0 1 2)
88+
~~~
89+
90+
This is related to the definition of `list*` in the HyperSpec: http://clhs.lisp.se/Body/f_list_.htm.
91+
6192

6293
### `vector`, `vector*`
6394

@@ -135,8 +166,12 @@ See https://github.com/guicho271828/trivia/wiki/Type-Based-Destructuring-Pattern
135166

136167
## Logic based patterns
137168

169+
We can combine any pattern with some logic.
170+
138171
### `and`, `or`
139172

173+
The following:
174+
140175
~~~lisp
141176
(match x
142177
((or (list 1 a)
@@ -151,23 +186,22 @@ matches against both `(1 2)` and `(4 . 3)` and returns 2 and 4, respectively.
151186
It does not match when subpattern matches. The variables used in the
152187
subpattern are not visible in the body.
153188

154-
### `guards`
189+
## Guards
190+
191+
Guards allow us to use patterns *and* to verify them against a predicate.
155192

156193
The syntax is `guard` + `subpattern` + `a test form`, and the body.
157194

158195
~~~lisp
159196
(match (list 2 5)
160-
((guard (list x y) ; subpattern
161-
(= 10 (* x y)) ; test-form
162-
(- x y) (satisfies evenp)) ; generator1, subpattern1
163-
t))
197+
((guard (list x y) ; subpattern1
198+
(= 10 (* x y))) ; test-form
199+
:ok))
164200
~~~
165201

166202
If the subpattern is true, the test form is evaluated, and if it is
167203
true it is matched against subpattern1.
168204

169-
The above returns `nil`, since `(- x y) == 3` does not satisfies `evenp`.
170-
171205

172206
## Nesting patterns
173207

0 commit comments

Comments
 (0)