Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MATCH-97: satisfies? calls for IMatchLookup perf issues
Breaking change, `c.c.match/match` no longer supports
`c.c.match.protocol/IMatchLookup`. The performance hit is too great when
recursively matching terms. The old behavior is provided for in a new
macro `c.c.match/matchm`.
  • Loading branch information
dnolen committed Dec 10, 2014
1 parent 0545c6a commit 5c1af7b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 17 deletions.
28 changes: 25 additions & 3 deletions src/main/clojure/clojure/core/match.clj
Expand Up @@ -57,6 +57,10 @@
(def ^{:dynamic true} *locals* nil)
(def ^{:dynamic true} *warned*)

(def ^{:dynamic true
:doc "Allow map matching syntax to check for IMatchLookup"}
*match-lookup* false)

(def ^{:dynamic true
:doc "Default vector type. Can be rebound allowing emission of
custom inline code for vector patterns, for example
Expand Down Expand Up @@ -1200,9 +1204,10 @@ col with the first column and compile the result"

IPatternCompile
(to-source* [this ocr]
(if *clojurescript*
`(satisfies? cljs.core/ILookup ~ocr)
`(or (instance? clojure.lang.ILookup ~ocr) (satisfies? IMatchLookup ~ocr))))
(cond
*clojurescript* `(satisfies? cljs.core/ILookup ~ocr)
*match-lookup* `(or (instance? clojure.lang.ILookup ~ocr) (satisfies? IMatchLookup ~ocr))
:else `(instance? clojure.lang.ILookup ~ocr)))

ISpecializeMatrix
(specialize-matrix [this matrix]
Expand Down Expand Up @@ -2026,6 +2031,23 @@ col with the first column and compile the result"
*warned* (atom false)]
`~(clj-form vars clauses)))

(defmacro matchm
"Same as match but supports IMatchLookup when
matching maps."
[vars & clauses]
(let [[vars clauses]
(if (vector? vars)
[vars clauses]
[(vector vars)
(mapcat (fn [[c a]]
[(if (not= c :else) (vector c) c) a])
(partition 2 clauses))])]
(binding [*match-lookup* true
*line* (-> &form meta :line)
*locals* (dissoc &env '_)
*warned* (atom false)]
`~(clj-form vars clauses))))

(defmacro match-let [bindings & body]
(let [bindvars# (take-nth 2 bindings)]
`(let ~bindings
Expand Down
2 changes: 1 addition & 1 deletion src/test/clojure/clojure/core/match/test/core.clj
Expand Up @@ -370,7 +370,7 @@

(deftest map-pattern-interop-1
(is (= (let [d (java.util.Date. 2010 10 1 12 30)]
(match [d]
(matchm [d]
[{:year 2009 :month a}] [:a0 a]
[{:year (:or 2010 2011) :month b}] [:a1 b]
:else []))
Expand Down
12 changes: 6 additions & 6 deletions src/test/clojure/clojure/core/match/test/date.clj
@@ -1,11 +1,11 @@
(ns clojure.core.match.test.date
(:use clojure.test)
(:use [clojure.core.match :only [match]])
(:use [clojure.core.match :only [matchm]])
(:use clojure.core.match.date))

(deftest date-test1
(is (= (match [(java.util.Date. 2010 10 1 12 30)]
[{:year 2009 :month a}] a
[{:year (:or 2010 2011) :month b}] b
:else :wrong)
10)))
(is (= (matchm [(java.util.Date. 2010 10 1 12 30)]
[{:year 2009 :month a}] a
[{:year (:or 2010 2011) :month b}] b
:else :wrong)
10)))
14 changes: 7 additions & 7 deletions src/test/clojure/clojure/core/match/test/java.clj
Expand Up @@ -7,16 +7,16 @@
(bean-match java.util.Date)

(deftest bean-match-date
(is (= 10 (match [(java.util.Date. 2009 10 1 12 30)]
[{:year 2009 :month a}] a
[{:year (:or 2010 2011) :month b}] b
:else :wrong))))
(is (= 10 (matchm [(java.util.Date. 2009 10 1 12 30)]
[{:year 2009 :month a}] a
[{:year (:or 2010 2011) :month b}] b
:else :wrong))))

(bean-match java.io.File)

(deftest bean-match-file
(is (= (.getAbsolutePath (java.io.File. "."))
(match [(java.io.File. ".")]
[{:directory? true :absolute-path p}] p
:else :wrong))))
(matchm [(java.io.File. ".")]
[{:directory? true :absolute-path p}] p
:else :wrong))))

0 comments on commit 5c1af7b

Please sign in to comment.