Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 333 lines (255 sloc) 8.047 kb
2394db7d » swannodette
2011-05-01 * README.md: textile -> md
1 match
2 ====
e0fa3b08 » swannodette
2011-04-12 * .gitignore: initial commit
3
c8ff9c5d » swannodette
2011-10-02 * README.md: ClojureScript support
4 An optimized pattern match and predicate dispatch library for Clojure. Currently the library only implements pattern matching. It supports Clojure 1.2.0 and later as well as ClojureScript.
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
5
2085bf17 » David Nolen
2012-04-25 * README.md: note alpha status
6 Alpha Status
7 ----
8 It's important to note that core.match is alpha quality software. There are many known issues. In particular if your project depends on AOT do not use core.match at this time. Patches for any and all issues welcome!
9
7291c16e » swannodette
2011-11-13 * README.md: update readme
10 Contributing
11 ----
12
13 No pull requests please. Please open tickets and submit patches to [JIRA](http://dev.clojure.org/jira/browse/MATCH)
14
15 For simple fixes you can message [swannodette](http://github.com/swannodette). Thanks.
16
440fa2d6 » swannodette
2011-08-18 * README.md: notes on usage
17 Usage
18 ----
19
20 The fastest way to use this library is with Leiningen or Cake. Add the following to your project.clj dependencies:
21
22 ```clojure
c484c5cb » swannodette
2012-01-04 * CHANGES.md: changes for next release
23 [org.clojure/core.match "0.2.0-alpha9"]
440fa2d6 » swannodette
2011-08-18 * README.md: notes on usage
24 ```
25
84959a92 » frenchy64
2011-09-21 Added usage help
26 Use via:
27
28 ```clojure
af647a77 » swannodette
2011-10-10 * README.md: MATCH-28: clojure.core.match ns instead of clojure.core.…
29 (use '[clojure.core.match :only [match]])
84959a92 » frenchy64
2011-09-21 Added usage help
30 ```
31
c8ff9c5d » swannodette
2011-10-02 * README.md: ClojureScript support
32 ClojureScript
33 ----
34
35 You can use match with ClojureScript by putting the match jar in $CLOJURESCRIPT_HOME/lib/. Then in your source file your namespace declaraction should look something like this:
36
37 ```clojure
e09a135b » swannodette
2011-10-02 * README.md: readme tweaks
38 (ns foo.bar
39 (:use-macros [clojure.core.match.js :only [match]]))
c8ff9c5d » swannodette
2011-10-02 * README.md: ClojureScript support
40 ```
41
440fa2d6 » swannodette
2011-08-18 * README.md: notes on usage
42 About
43 ----
44
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
45 This library implements a pattern match compilation algorithm that uses the notion of "necessity" from lazy pattern matching.
46
47 For example the following pattern:
48
49 ```clojure
50 (let [x true
51 y true
52 z true]
53 (match [x y z]
54 [_ false true] 1
55 [false true _ ] 2
56 [_ _ false] 3
57 [_ _ true] 4))
58 ```
59
4d5c15dc » swannodette
2011-09-13 * README.md: change wording in about example
60 expands into something similar to the following:
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
61
62 ```clojure
63 (cond
64 (= y false) (cond
65 (= z false) (let [] 3)
66 (= z true) (let [] 1)
1b7cb8af » swannodette
2011-08-18 * README.md: update readme w/ new fail node text
67 :else (throw (java.lang.Exception. "No match found.")))
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
68 (= y true) (cond
69 (= x false) (let [] 2)
70 :else (cond
71 (= z false) 3
72 (= z true) 4
73 :else (throw
74 (java.lang.Exception.
1b7cb8af » swannodette
2011-08-18 * README.md: update readme w/ new fail node text
75 "No match found."))))
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
76 :else (cond
77 (= z false) (let [] 3)
78 (= z true) (let [] 4)
1b7cb8af » swannodette
2011-08-18 * README.md: update readme w/ new fail node text
79 :else (throw (java.lang.Exception. "No match found."))))
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
80 ```
81
4c62a612 » swannodette
2011-08-09 * src/match/perf.clj: readme typo
82 Note that y gets tested first. Lazy pattern matching consistently gives compact decision trees. This means faster pattern matching. You can find out more in the top paper cited below.
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
83
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
84 Matching literals
85 ----
86
87 ```clojure
88 (let [x true
89 y true
90 z true]
91 (match [x y z]
92 [_ false true] 1
93 [false true _ ] 2
94 [_ _ false] 3
95 [_ _ true] 4))
96 ;; => 4
2394db7d » swannodette
2011-05-01 * README.md: textile -> md
97 ```
20e6ec31 » swannodette
2011-04-12 * readme.textile: illustration
98
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
99 Wherever you would use a wildcard you can use a binding:
100
101 ```clojure
102 (let [x 1 y 2 z 4]
103 (match [x y z]
104 [1 2 b] [:a0 b]
105 [a 2 4] [:a1 a]))
106 ;; => [:a0 4]
107 ```
108
2522d52e » swannodette
2011-08-28 * README.md: update documentation on vector patterns
109 Vector matching
110 ----
111
112 Vector patterns support pattern matching any data type that supports the notion of random access. Clojure's persistent vectors are supported out of the box - note however the feature is extensible to primitive arrays and even for pattern matching bits in a primitive byte.
113
114 ```clojure
115 (let [v [1 2 3]]
116 (match [v]
117 [[1 1 1]] :a0
118 [[1 2 1]] :a1
119 [[1 2 _]] :a2))
120 ;; => :a2
121 ```
122
123 Vector patterns also support the familiar rest syntax from destructuring.
124
125 ```clojure
126 (let [v [3 2 3]]
127 (match [v]
128 [[1 1 3]] :a0
129 [[2 & r]] :a1
130 [[3 & r]] :a2))
131 ;; => :a2
132 ```
133
134 It's simple to extend match to support primitive arrays so you can write the following:
135
136 ```clojure
60d4d532 » swannodette
2011-10-02 * README.md: minor tweak
137 (defn balance [^objects node]
4346b5ad » swannodette
2011-10-02 * README.md: cleanup RB Tree example
138 (matchv ::objects [node]
00dd8a71 » swannodette
2011-10-28 * README.md: update or pattern syntax in readme
139 [(:or [:black [:red [:red a x b] y c] z d]
140 [:black [:red a x [:red b y c]] z d]
141 [:black a x [:red [:red b y c] z d]]
142 [:black a x [:red b y [:red c z d]]])] (R (B a x b) y (B c z d))))
2522d52e » swannodette
2011-08-28 * README.md: update documentation on vector patterns
143 ```
144
145 See <code>match.array</code> for some ideas.
146
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
147 Seq matching
148 ----
149
2522d52e » swannodette
2011-08-28 * README.md: update documentation on vector patterns
150 Seq patterns are optimized for working with sequences.
151
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
152 ```clojure
153 (let [x [1 2 nil nil nil]]
154 (match [x]
2522d52e » swannodette
2011-08-28 * README.md: update documentation on vector patterns
155 [([1] :seq)] :a0
156 [([1 2] :seq)] :a1
157 [([1 2 nil nil nil] :seq)] :a2))
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
158 ;; => :a2
159 ```
160
10b1f9f9 » swannodette
2011-08-09 * README.md: fix typos in readm
161 Seq patterns also support the familiar rest syntax from destructuring.
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
162
163 ```clojure
164 (let [x '(1 2 3 4)]
165 (match [x]
2522d52e » swannodette
2011-08-28 * README.md: update documentation on vector patterns
166 [([1] :seq)] :a0
167 [([_ 2 & ([a & b] :seq)] :seq)] [:a1 a b]))
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
168 ;; => [:a1 3 '(4)]
169 ```
170
171 Map matching
172 ----
173
174 ```clojure
175 (let [x {:a 1 :b 1}]
176 (match [x]
f2fd4611 » swannodette
2011-08-19 * README.md: change to normal map syntax
177 [{:a _ :b 2}] :a0
178 [{:a 1 :c _}] :a1
179 [{:c 3 :d _ :e 4}] :a2))
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
180 ;; => :a1
181 ```
182
10b1f9f9 » swannodette
2011-08-09 * README.md: fix typos in readm
183 You can constrain map matching so that only maps with the exact key set will match:
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
184
185 ```clojure
186 (match [x]
f2fd4611 » swannodette
2011-08-19 * README.md: change to normal map syntax
187 [({:a _ :b 2} :only [:a :b])] :a0
188 [{:a 1 :c c}] :a1
189 [{:c 3 :d d :e 4}] :a2)
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
190 ```
191
c8e9feda » frenchy64
2011-08-13 Moved list syntax explanation
192 Special Syntax
193 ----
194
195 The list syntax `()` is reserved for special uses. It does *not* match a literal list.
196
197 Or Patterns, Guards and As Patterns use this syntax.
198
199
03741ca9 » swannodette
2011-08-12 * README.md: update readme about or patterns
200 Or Patterns
201 ----
202
203 Or patterns are supported anywhere you would use a pattern:
204
205 ```clojure
206 (let [x '(1 2 3)]
c563d40f » swannodette
2011-09-13 * README.md: fix typo in or patterns in readme
207 (match [x]
00dd8a71 » swannodette
2011-10-28 * README.md: update or pattern syntax in readme
208 [[1 (:or 3 4) 3]] :a0
209 [[1 (:or 2 3) 3]] :a1))
29b19b60 » swannodette
2011-08-12 * README.md: update readme
210 ;; => :a1
03741ca9 » swannodette
2011-08-12 * README.md: update readme about or patterns
211
212 (let [x {:a 3}]
c563d40f » swannodette
2011-09-13 * README.md: fix typo in or patterns in readme
213 (match [x]
00dd8a71 » swannodette
2011-10-28 * README.md: update or pattern syntax in readme
214 [{:a (:or 1 2)}] :a0
215 [{:a (:or 3 4)}] :a1))
2d1177d8 » swannodette
2011-08-12 * README.md: update readme about guards
216 ;; => :a1
217 ```
218
219 Guards
220 ----
221
222 Guards are simple boolean tests. You can specify them like so:
223
224 ```clojure
225 (let [y '(2 3 4 5)]
226 (match [y]
227 [[_ (a :when even?) _ _]] :a0
228 [[_ (b :when [odd? div3?]) _ _]] :a1))
229 ;; => :a1
03741ca9 » swannodette
2011-08-12 * README.md: update readme about or patterns
230 ```
231
b100d5b0 » swannodette
2012-01-10 * README.md: note the current limitations of guards
232 Please note that neither inline function expressions <code>(fn ...)</code> nor
233 <code>#(foo %)</code> are currently supported.
234
29b19b60 » swannodette
2011-08-12 * README.md: update readme
235 As Patterns
236 ----
237
d0a7742c » swannodette
2011-08-17 * README.md: typo
238 Sometimes you'd like capture a part of the match with a binding:
29b19b60 » swannodette
2011-08-12 * README.md: update readme
239
240 ```clojure
241 (let [v [[1 2]]]
242 (match [v]
cd4f6ffc » swannodette
2011-09-13 * README.md: another tweak
243 [[[3 1]]] :a0
4a156ee9 » swannodette
2011-09-13 * README.md: real fix for typo
244 [[([1 a] :as b)]] [:a1 a b]))
4643a5b7 » swannodette
2011-11-14 * README.md: fix typo in example
245 ;; => [:a1 2 [1 2]]
29b19b60 » swannodette
2011-08-12 * README.md: update readme
246 ```
247
127c9431 » swannodette
2011-08-12 * README.md: java interop example
248 Java Interop
249 ----
250
6271e69d » swannodette
2011-08-13 * README.md: minor typo
251 By extending Java types to IMatchLookup, Java types can participate in map patterns:
127c9431 » swannodette
2011-08-12 * README.md: java interop example
252
253 ```clojure
254 (extend-type java.util.Date
255 IMatchLookup
256 (val-at* [this k not-found]
257 (case k
258 :year (.getYear this)
259 :month (.getMonth this)
260 :date (.getDate this)
261 :hours (.getHours this)
262 :minutes (.getMinutes this)
263 not-found)))
264
265 (let [d (java.util.Date. 2010 10 1 12 30)]
266 (match [d]
f2fd4611 » swannodette
2011-08-19 * README.md: change to normal map syntax
267 [{:year 2009 :month a}] [:a0 a]
00dd8a71 » swannodette
2011-10-28 * README.md: update or pattern syntax in readme
268 [{:year (:or 2010 2011) :month b}] [:a1 b]))
127c9431 » swannodette
2011-08-12 * README.md: java interop example
269 ;; => [:a1 10]
270 ```
271
f96257c0 » swannodette
2011-08-28 * README.md: update readme with bean-match example
272 The above is a bit tedious to write so <code>match.java</code> supplies a <code>bean-match</code> macro that can be used as follows:
273
2ac072e1 » swannodette
2011-08-28 * README.md: typo
274 ```clojure
f96257c0 » swannodette
2011-08-28 * README.md: update readme with bean-match example
275 (bean-match java.awt.Color)
276 (match [java.awt.Color/RED]
277 [{:red red :green green :blue blue}] [red green blue]
278 :else :error)
279 ;; => [255 0 0]
280 ```
281
3415a343 » frenchy64
2011-08-13 Note on Pattern Rows
282 Note on Pattern Rows
283 ----
284
285 A pattern row is delimited with `[]`, and is not a pattern itself.
286
287 For example, this syntax is illegal:
288
289 ```clojure
290 (let [v 1]
291 (match [v]
292 ([1] :as w) :a0) ;; Illegal! [1] is a pattern row, not a pattern.
293 ```
294
a4aa7d16 » frenchy64
2011-08-19 Added description of match-1 in readme
295 Matching single variables
296 ---
297
67afdaba » swannodette
2011-10-28 * README.md: update documentation
298 Matching single variables is simple:
a4aa7d16 » frenchy64
2011-08-19 Added description of match-1 in readme
299
300 ```clojure
301 (let [x 3]
67afdaba » swannodette
2011-10-28 * README.md: update documentation
302 (match x
303 1 :a0
304 2 :a1
305 :else :a2))
a4aa7d16 » frenchy64
2011-08-19 Added description of match-1 in readme
306 ;=> :a2
307 ```
308
385f3091 » swannodette
2011-10-28 * README.md: tweak
309 Note that <code>:else</code> clauses are special and never need to be wrapped.
a4aa7d16 » frenchy64
2011-08-19 Added description of match-1 in readme
310
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
311 Road Map
312 ----
313
3767a201 » swannodette
2011-08-12 * README.md: tweak
314 A good chunk of Maranget's algorithm for pattern matching has been implemented. We would like to flesh out the pattern matching functionality. Once that work is done, we'll move on to predicate dispatch.
5c9e9976 » swannodette
2011-08-09 * README.md: update readme
315
2394db7d » swannodette
2011-05-01 * README.md: textile -> md
316 Resources
317 ----
e0fa3b08 » swannodette
2011-04-12 * .gitignore: initial commit
318
706799ba » swannodette
2011-07-30 * README.md: update readme with hash-consing paper
319 The four most relevant papers:
b48a854f » swannodette
2011-05-23 * README.md: notes, highlight releveant papers, scratch stuff
320
7d715f21 » swannodette
2011-08-02 * README.md: fix readme link. small code cleanup pass.
321 * [Compiling Pattern Matching to Good Decision Trees](http://pauillac.inria.fr/~maranget/papers/ml05e-maranget.pdf)
223c2d2f » swannodette
2011-08-09 * README.md: readme tweaks
322 * [Efficient Predicate Dispatch](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.47.4553)
d76b0ab9 » swannodette
2011-07-30 * README.md: typo
323 * [Warnings for Pattern Matching](http://moscova.inria.fr/~maranget/papers/warn/index.html)
c3cfde3c » swannodette
2011-08-19 * README.md: remove paper move paper up
324 * [Extensible Pattern Matching for Extensible Languages](http://www.ccs.neu.edu/home/samth/ifl2010-slides.pdf)
b48a854f » swannodette
2011-05-23 * README.md: notes, highlight releveant papers, scratch stuff
325
326 Further reading:
53d99581 » swannodette
2011-08-19 * README.md: typo
327
4182c7c7 » swannodette
2011-05-09 * README.md: more reading and more sketching
328 * [Optimizing Pattern Matching](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.5507)
329 * [Pattern Guards And Transformational Patterns](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.35.8851)
2394db7d » swannodette
2011-05-01 * README.md: textile -> md
330 * [Art of the Metaobject Protocol](http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=3925)
a4c39027 » swannodette
2011-05-19 * README.md: new reference, minor perf note and scratch changes
331 * [Custom Specializers in Object-Oriented Lisp](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.144.405&rep=rep1&type=pdf)
2e726dc9 » swannodette
2011-04-12 * license.txt: added license, updated readme
332
333 Distributed under the Eclipse Public License, the same as Clojure.
Something went wrong with that request. Please try again.