Musing on applying transducer to conj, below the fold.
;; suppose:
(def a (atom nil))
(defn callback'
[x]
(swap! a conj x))
;; need to transform x before conj
;; want to use transducer.
;; why? Maybe transducer exists already,
;; maybe transformation is best expressed as transducer (stateful, filters, etc)
;;
;; well, conj is a reducing function, so we can replace it
;; with (xf conj) thus:
(def xf
(comp
(filter odd?)
(map inc)))
(def rf
(xf conj))
(defn callback [x]
(swap! a rf x))
;; simulate activity:
(callback 7) ; (8)
(callback 8) ; (8)
(callback 7) ; (8 8)
;; of course, callback could have been
(defn callback' [x]
(if (odd? x)
(swap! a conj (inc x))
@a))
;; and if you had a stateful transducer you could have written callback as a let-over-lambda:
(def xf'' (dedupe))
(def rf'' (xf'' conj))
;; equivalent callback'':
(let [b (atom nil)]
(defn callback'' [x]
(let [b' @b]
(reset! b x)
(if (not= b' x)
(swap! a conj x)
@a))))
;; but i think it more likely to screw this up than just
;; (comp (dedupe) (filter odd?) (map inc) #_(maybe more transducers et cetera))
;; which makes this another way to say how crazy good the transducer concept isswap! may call its argument more than once, so stateful transducers are precluded
thanks—nice catch