From eb2867de647795566f0adc12efcb84ed4ba6eec2 Mon Sep 17 00:00:00 2001
From: Alan Malloy <alan@malloys.org>
Date: Thu, 10 May 2012 19:39:36 -0700
Subject: [PATCH] Add reducers/iterate.

---
 src/clj/clojure/core/reducers.clj      |   16 +++++++++++++++-
 test/clojure/test_clojure/reducers.clj |    7 +++++++
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/src/clj/clojure/core/reducers.clj b/src/clj/clojure/core/reducers.clj
index efe6118..19c86db 100644
--- a/src/clj/clojure/core/reducers.clj
+++ b/src/clj/clojure/core/reducers.clj
@@ -13,7 +13,7 @@
       dependency info."
       :author "Rich Hickey"}
   clojure.core.reducers
-  (:refer-clojure :exclude [reduce map mapcat filter remove take take-while drop flatten])
+  (:refer-clojure :exclude [reduce map mapcat filter remove take take-while drop flatten iterate])
   (:require [clojure.walk :as walk]))
 
 (alias 'core 'clojure.core)
@@ -300,6 +300,20 @@
       :else
       (Cat. (+ (count left) (count right)) left right))))
 
+(defcurried iterate
+  "A reducible collection of [seed, (f seed), (f (f seed)), ...]"
+  {:added "1.5"}
+  [f seed]
+  (reify
+    clojure.core.protocols/CollReduce
+    (coll-reduce [this f1] (clojure.core.protocols/coll-reduce this f1 (f1)))
+    (coll-reduce [this f1 init]
+      (loop [ret (f1 init seed), seed seed]
+        (if (reduced? ret)
+          @ret
+          (let [next (f seed)]
+            (recur (f1 ret next) next)))))))
+
 (defn append!
   ".adds x to acc and returns acc"
   {:added "1.5"}
diff --git a/test/clojure/test_clojure/reducers.clj b/test/clojure/test_clojure/reducers.clj
index 1123c36..8d4e789 100644
--- a/test/clojure/test_clojure/reducers.clj
+++ b/test/clojure/test_clojure/reducers.clj
@@ -39,3 +39,10 @@
 (defequivtest test-filter
   [filter r/filter #(into [] %)]
   [even? odd? #(< 200 %) identity])
+
+(deftest test-iterate
+  (is (= [100000]
+         (->> (r/iterate inc 0)
+              (r/drop 1e5)
+              (r/take 1)
+              (into [])))))
-- 
1.7.4.1

