(eduction xform* coll)
Returns a reducible/iterable application of the transducers to the items in coll. Transducers are applied in order as if combined with comp. Note that these applications will be performed every time reduce/iterator is called.
;; inc with debugging output
(defn inc-with-print [x]
(println x)
(inc x))
(eduction (map inc-with-print) (map inc-with-print) (range 3))
;; 0
;; 1
;; 1
;; 2
;; 2
;; 3
;;=> (2 3 4)
(->> (range 3)
(map inc-with-print)
(map inc-with-print))
;; 0
;; 1
;; 2
;; 1
;; 2
;; 3
;;=> (2 3 4)
;; Explanation by freckletonj ---------------------
;; It took me a minute to figure out the documentation and this example.
;; Here's what's going on with the call order:
;;
;; in the `eduction` example, the calling order looks like -
;; (map #(inc-with-print (inc-with-print %)) (range 3))
;; where as in the `->>` thread example, it looks like -
;; (map #(inc-with-print %)
;; (map #(inc-with-print %) (range 3)))
;;
;; So, `eduction` calls the stack of transformers on each element, each time
;; `->>` calls transformer 1 on a collection, then transformer 2 on the result, etc.
;; eduction: just run an xform over a collection
(eduction (map inc) [1 2 3]) ; => (2 3 4)
(eduction (filter even?) (range 5)) ; => (0 2 4)
;; several transducers can be given, without using 'comp'
(eduction (filter even?) (map inc)
(range 5)) ; => (1 3 5)
;; This will run out of memory eventually,
;; because the entire seq is realized,
;; because the head of the lazy seq is retained.
(let
[s (range 100000000)]
(do (apply print s) (first s)))
;; This iterates through the lazy seq without realizing the seq.
(let
[s (eduction identity (range 100000000))]
(do (apply print s) (first s)))
;; Result of eduction is of clojure.core.Eduction type which acts as a lazy
;; collection that re-executes all the steps again and again. This could be
;; useful when you don't want to store the collection separately.
;;
;; Eductions can be efficiently used with reduce and transduce.
(def ed (eduction (map inc-with-print) (map inc-with-print) (range 3)))
(defn identity-with-print [x]
(println "identity:" x)
x)
(map identity-with-print ed)
;; 0
;; 1
;; 1
;; 2
;; 2
;; 3
;; identity: 2
;; identity: 3
;; identity: 4
;; => (2 3 4)
(defn sum-with-print [x y]
(println "sum:" x "+" y)
(+ x y))
(reduce sum-with-print ed)
;; 0
;; 1
;; 1
;; 2
;; sum: 2 + 3
;; 2
;; 3
;; sum: 5 + 4
;; => 9
(transduce (map identity-with-print) + ed)
;; 0
;; 1
;; identity: 2
;; 1
;; 2
;; identity: 3
;; 2
;; 3
;; identity: 4
;; 1496674214GET/accounts{}
;; => 9