diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-06-20 12:11:35 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-06-20 12:11:35 -0400 |
commit | 2a5fa05b05c880a1f08110edaabf644b8a39e6ea (patch) | |
tree | 43daea3c5dfffe651a833e41fabb8fa5a65da934 | |
parent | cf3b547e7d8f95d6e4234881f8122bb823ff46cd (diff) |
made reduce chunk-aware
-rw-r--r-- | src/clj/clojure/core.clj | 166 |
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 |