Transducers
;; A transducer is a composable transformation, independent of input and output sources
(def xf (comp (filter odd?)
(map inc)
(take 3)))
(into [] xf (range 20)) ; [2 4 6]
(transduce xf + (range 20)) ; 12
(sequence xf (range 20)) ; (2 4 6): lazy
(eduction xf (range 20)) ; reducible/iterable, recomputed on each use
(transduce (map count) + ["a" "bb" "ccc"]) ; 6
;; Most sequence functions return a transducer when called without a collection:
;; map filter remove keep mapcat take take-while drop drop-while partition-by partition-all
;; dedupe distinct cat interpose replace halt-when random-sample
(into #{} (comp cat (map keyword)) [["a" "b"] ["c"]]) ; #{:a :b :c}
;; Benefits: no intermediate collections, reusable across collections/channels/streams
;; core.async channels accept transducers: (chan 10 (filter even?))
;; Writing a transducer
(defn my-map [f]
(fn [rf]
(fn
([] (rf))
([result] (rf result))
([result input] (rf result (f input))))))
(into [] (my-map #(* 10 %)) [1 2 3]) ; [10 20 30]
;; reduced: early termination
(reduce (fn [acc x] (if (> acc 10) (reduced acc) (
…