Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: clojure/clojure
...
head fork: clojure/clojure
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
View
7 src/clj/clojure/core.clj
@@ -6025,12 +6025,9 @@
items, returns val and f is not called."
{:added "1.0"}
([f coll]
- (if-let [s (seq coll)]
- (reduce f (first s) (next s))
- (f)))
+ (clojure.core.protocols/coll-reduce coll f))
([f val coll]
- (let [s (seq coll)]
- (clojure.core.protocols/internal-reduce s f val))))
+ (clojure.core.protocols/coll-reduce coll f val)))
(extend-protocol clojure.core.protocols/IKVReduce
;;slow path default
View
62 src/clj/clojure/core/protocols.clj
@@ -10,11 +10,73 @@
(set! *warn-on-reflection* true)
+(defprotocol CollReduce
+ "Protocol for collection types that can implement reduce faster than
+ first/next recursion. Called by clojure.core/reduce. Baseline
+ implementation defined in terms of Iterable."
+ (coll-reduce [coll f] [coll f val]))
+
(defprotocol InternalReduce
"Protocol for concrete seq types that can reduce themselves
faster than first/next recursion. Called by clojure.core/reduce."
(internal-reduce [seq f start]))
+(defn- seq-reduce
+ ([coll f]
+ (if-let [s (seq coll)]
+ (internal-reduce (next s) f (first s))
+ (f)))
+ ([coll f val]
+ (let [s (seq coll)]
+ (internal-reduce s f val))))
+
+(extend-protocol CollReduce
+ nil
+ (coll-reduce
+ ([coll f] (f))
+ ([coll f val] val))
+
+ Object
+ (coll-reduce
+ ([coll f] (seq-reduce coll f))
+ ([coll f val] (seq-reduce coll f val)))
+
+ ;;aseqs are iterable, masking internal-reducers
+ clojure.lang.ASeq
+ (coll-reduce
+ ([coll f] (seq-reduce coll f))
+ ([coll f val] (seq-reduce coll f val)))
+
+ ;;for range
+ clojure.lang.LazySeq
+ (coll-reduce
+ ([coll f] (seq-reduce coll f))
+ ([coll f val] (seq-reduce coll f val)))
+
+ ;;vector's chunked seq is faster than its iter
+ clojure.lang.PersistentVector
+ (coll-reduce
+ ([coll f] (seq-reduce coll f))
+ ([coll f val] (seq-reduce coll f val)))
+
+ Iterable
+ (coll-reduce
+ ([coll f]
+ (let [iter (.iterator coll)]
+ (if (.hasNext iter)
+ (loop [ret (.next iter)]
+ (if (.hasNext iter)
+ (recur (f ret (.next iter)))
+ ret))
+ (f))))
+ ([coll f val]
+ (let [iter (.iterator coll)]
+ (loop [ret val]
+ (if (.hasNext iter)
+ (recur (f ret (.next iter)))
+ ret)))))
+ )
+
(extend-protocol InternalReduce
nil
(internal-reduce
View
1  src/clj/clojure/core_deftype.clj
@@ -205,6 +205,7 @@
(clojure.lang.MapEntry. k# v#))))
`(seq [this#] (seq (concat [~@(map #(list `new `clojure.lang.MapEntry (keyword %) %) base-fields)]
~'__extmap)))
+ `(iterator [this#] (clojure.lang.SeqIterator. (.seq this#)))
`(assoc [this# k# ~gs]
(condp identical? k#
~@(mapcat (fn [fld]

No commit comments for this range

Something went wrong with that request. Please try again.