summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-06-20 12:11:35 -0400
committerRich Hickey <richhickey@gmail.com>2009-06-20 12:11:35 -0400
commit2a5fa05b05c880a1f08110edaabf644b8a39e6ea (patch)
tree43daea3c5dfffe651a833e41fabb8fa5a65da934
parentcf3b547e7d8f95d6e4234881f8122bb823ff46cd (diff)
made reduce chunk-aware
-rw-r--r--src/clj/clojure/core.clj166
1 files changed, 85 insertions, 81 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 043e6ad4..e2162032 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -513,6 +513,78 @@
(if or# or# (or ~@next)))))
;;;;;;;;;;;;;;;;;;; sequence fns ;;;;;;;;;;;;;;;;;;;;;;;
+(defn zero?
+ "Returns true if num is zero, else false"
+ {:tag Boolean
+ :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))}
+ [x] (. clojure.lang.Numbers (isZero x)))
+
+(defn count
+ "Returns the number of items in the collection. (count nil) returns
+ 0. Also works on strings, arrays, and Java Collections and Maps"
+ [coll] (clojure.lang.RT/count coll))
+
+(defn int
+ "Coerce to int"
+ {:tag Integer
+ :inline (fn [x] `(. clojure.lang.RT (intCast ~x)))}
+ [x] (. clojure.lang.RT (intCast x)))
+
+(defn nth
+ "Returns the value at the index. get returns nil if index out of
+ bounds, nth throws an exception unless not-found is supplied. nth
+ also works for strings, Java arrays, regex Matchers and Lists, and,
+ in O(n) time, for sequences."
+ {:inline (fn [c i] `(. clojure.lang.RT (nth ~c ~i)))
+ :inline-arities #{2}}
+ ([coll index] (. clojure.lang.RT (nth coll index)))
+ ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))
+
+(defn <
+ "Returns non-nil if nums are in monotonically increasing order,
+ otherwise false."
+ {:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y)))
+ :inline-arities #{2}}
+ ([x] true)
+ ([x y] (. clojure.lang.Numbers (lt x y)))
+ ([x y & more]
+ (if (< x y)
+ (if (next more)
+ (recur y (first more) (next more))
+ (< y (first more)))
+ false)))
+
+(defn inc
+ "Returns a number one greater than num."
+ {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x)))}
+ [x] (. clojure.lang.Numbers (inc x)))
+
+(defn chunk-buffer [capacity]
+ (clojure.lang.ChunkBuffer. capacity))
+
+(defn chunk-append [#^clojure.lang.ChunkBuffer b x]
+ (.add b x))
+
+(defn chunk [#^clojure.lang.ChunkBuffer b]
+ (.chunk b))
+
+(defn #^clojure.lang.IChunk chunk-first [#^clojure.lang.IChunkedSeq s]
+ (.chunkedFirst s))
+
+(defn #^clojure.lang.ISeq chunk-rest [#^clojure.lang.IChunkedSeq s]
+ (.chunkedMore s))
+
+(defn #^clojure.lang.ISeq chunk-next [#^clojure.lang.IChunkedSeq s]
+ (.chunkedNext s))
+
+(defn chunk-cons [chunk rest]
+ (if (zero? (count chunk))
+ rest
+ (clojure.lang.ChunkedCons. chunk rest)))
+
+(defn chunked-seq? [s]
+ (instance? clojure.lang.IChunkedSeq s))
+
(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
@@ -526,19 +598,21 @@
([f coll]
(let [s (seq coll)]
(if s
- (if (instance? clojure.lang.IReduce s)
- (. #^clojure.lang.IReduce s (reduce f))
- (reduce f (first s) (next s)))
+ (reduce f (first s) (next s))
(f))))
([f val coll]
(let [s (seq coll)]
- (if (instance? clojure.lang.IReduce s)
- (. #^clojure.lang.IReduce s (reduce f val))
- ((fn [f val s]
- (if s
- (recur f (f val (first s)) (next s))
- val))
- f val s)))))
+ (if s
+ (if (chunked-seq? s)
+ (recur f
+ (let [c (chunk-first s)]
+ (loop [val val i (int 0)]
+ (if (< i (count c))
+ (recur (f val (nth c i)) (inc i))
+ val)))
+ (chunk-next s))
+ (recur f (f val (first s)) (next s)))
+ val))))
(defn reverse
"Returns a seq of the items in coll in reverse order. Not lazy."
@@ -586,20 +660,6 @@
([x y & more]
(reduce - (- x y) more)))
-(defn <
- "Returns non-nil if nums are in monotonically increasing order,
- otherwise false."
- {:inline (fn [x y] `(. clojure.lang.Numbers (lt ~x ~y)))
- :inline-arities #{2}}
- ([x] true)
- ([x y] (. clojure.lang.Numbers (lt x y)))
- ([x y & more]
- (if (< x y)
- (if (next more)
- (recur y (first more) (next more))
- (< y (first more)))
- false)))
-
(defn <=
"Returns non-nil if nums are in monotonically non-decreasing order,
otherwise false."
@@ -669,11 +729,6 @@
([x y & more]
(reduce min (min x y) more)))
-(defn inc
- "Returns a number one greater than num."
- {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x)))}
- [x] (. clojure.lang.Numbers (inc x)))
-
(defn dec
"Returns a number one less than num."
{:inline (fn [x] `(. clojure.lang.Numbers (dec ~x)))}
@@ -739,12 +794,6 @@
:inline (fn [x] `(. clojure.lang.Numbers (isNeg ~x)))}
[x] (. clojure.lang.Numbers (isNeg x)))
-(defn zero?
- "Returns true if num is zero, else false"
- {:tag Boolean
- :inline (fn [x] `(. clojure.lang.Numbers (isZero ~x)))}
- [x] (. clojure.lang.Numbers (isZero x)))
-
(defn quot
"quot[ient] of dividing numerator by denominator."
[num div]
@@ -846,10 +895,7 @@
-(defn count
- "Returns the number of items in the collection. (count nil) returns
- 0. Also works on strings, arrays, and Java Collections and Maps"
- [coll] (. clojure.lang.RT (count coll)))
+
;;list stuff
(defn peek
@@ -864,16 +910,6 @@
as next/butlast."
[coll] (. clojure.lang.RT (pop coll)))
-(defn nth
- "Returns the value at the index. get returns nil if index out of
- bounds, nth throws an exception unless not-found is supplied. nth
- also works for strings, Java arrays, regex Matchers and Lists, and,
- in O(n) time, for sequences."
- {:inline (fn [c i] `(. clojure.lang.RT (nth ~c ~i)))
- :inline-arities #{2}}
- ([coll index] (. clojure.lang.RT (nth coll index)))
- ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))
-
;;map stuff
(defn contains?
@@ -1493,38 +1529,6 @@
:arglists '([pred coll])}
not-any? (comp not some))
-(defn chunk-buffer [capacity]
- (clojure.lang.ChunkBuffer. capacity))
-
-(defn chunk-append [#^clojure.lang.ChunkBuffer b x]
- (.add b x))
-
-(defn chunk [#^clojure.lang.ChunkBuffer b]
- (.chunk b))
-
-(defn #^clojure.lang.IChunk chunk-first [#^clojure.lang.IChunkedSeq s]
- (.chunkedFirst s))
-
-(defn #^clojure.lang.ISeq chunk-rest [#^clojure.lang.IChunkedSeq s]
- (.chunkedMore s))
-
-(defn #^clojure.lang.ISeq chunk-next [#^clojure.lang.IChunkedSeq s]
- (.chunkedNext s))
-
-(defn chunk-cons [chunk rest]
- (if (zero? (count chunk))
- rest
- (clojure.lang.ChunkedCons. chunk rest)))
-
-(defn chunked-seq? [s]
- (instance? clojure.lang.IChunkedSeq s))
-
-(defn int
- "Coerce to int"
- {:tag Integer
- :inline (fn [x] `(. clojure.lang.RT (intCast ~x)))}
- [x] (. clojure.lang.RT (intCast x)))
-
;will be redefed later with arg checks
(defmacro dotimes
"bindings => name n