Permalink
Browse files

CLJS-232: remove (extend-type default IReduce ...)

This commit removes the default implementation of IReduce and patches
cljs.core/reduce to check if its collection argument implements
IReduce before delegating to -reduce.

For non-implementing collection types, the private helper function
seq-reduce is now called which rolls over to -reduce as soon as
possible.

A new predicate cljs.core/reducible? is also introduced.
  • Loading branch information...
1 parent fda0500 commit 1105d86ea3fa2109eb941f4ce6ebf61d1a16c4ea @michalmarczyk michalmarczyk committed with David Nolen May 2, 2012
Showing with 25 additions and 25 deletions.
  1. +25 −25 src/cljs/cljs/core.cljs
@@ -750,6 +750,10 @@ reduces them without incurring seq initialization"
"Returns true if coll implements nth in constant time"
[x] (satisfies? IIndexed x))
+(defn ^boolean reducible?
+ "Returns true if coll satisfies IReduce"
+ [x] (satisfies? IReduce x))
+
(defn ^boolean map?
"Return true if x satisfies IMap"
[x]
@@ -943,6 +947,21 @@ reduces them without incurring seq initialization"
([keyfn comp coll]
(sort (fn [x y] ((fn->comparator comp) (keyfn x) (keyfn y))) coll)))
+; simple reduce based on seqs, used as default
+(defn- seq-reduce
+ ([f coll]
+ (if-let [s (seq coll)]
+ (reduce f (first s) (next s))
+ (f)))
+ ([f val coll]
+ (loop [val val, coll (seq coll)]
+ (if coll
+ (let [nval (f val (first coll))]
+ (if (reduced? nval)
+ @nval
+ (recur nval (next coll))))
+ val))))
+
(defn reduce
"f should be a function of 2 arguments. If val is not supplied,
returns the result of applying f to the first 2 items in coll, then
@@ -954,9 +973,13 @@ reduces them without incurring seq initialization"
applying f to that result and the 2nd item, etc. If coll contains no
items, returns val and f is not called."
([f coll]
- (-reduce coll f))
+ (if (reducible? coll)
+ (-reduce coll f)
+ (seq-reduce f coll)))
([f val coll]
- (-reduce coll f val)))
+ (if (reducible? coll)
+ (-reduce coll f val)
+ (seq-reduce f val coll))))
(defn reduce-kv
"Reduces an associative collection. f should be a function of 3
@@ -968,29 +991,6 @@ reduces them without incurring seq initialization"
([f init coll]
(-kv-reduce coll f init)))
-; simple reduce based on seqs, used as default
-(defn- seq-reduce
- ([f coll]
- (if-let [s (seq coll)]
- (reduce f (first s) (next s))
- (f)))
- ([f val coll]
- (loop [val val, coll (seq coll)]
- (if coll
- (let [nval (f val (first coll))]
- (if (reduced? nval)
- @nval
- (recur nval (next coll))))
- val))))
-
-(extend-type default
- IReduce
- (-reduce
- ([coll f]
- (seq-reduce f coll))
- ([coll f start]
- (seq-reduce f start coll))))
-
(deftype Reduced [val]
IDeref
(-deref [o] val))

0 comments on commit 1105d86

Please sign in to comment.