Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save finalfantasia/1825e62e36f0e63bc5ff4a0ea396ca02 to your computer and use it in GitHub Desktop.
Save finalfantasia/1825e62e36f0e63bc5ff4a0ea396ca02 to your computer and use it in GitHub Desktop.
Understanding Transducer Composition in Clojure
;; this is a little Clojure code snippet that hopefully helps one understand why
;; the order in which components of a composite transducer passed to the `comp`
;; fn feels backward when compared to that of regular fn compositions.
;; in the following `defn`s, `rf` is a "reducing fn", i.e., any fn that `reduce`
;; expects as its first argument (e.g., `+`, `conj`, etc.)
;; a transducer
(defn g [rf]
(fn [r x] ; this fn itself is a reducing fn
(print "g: ") ; our contrived transformation of `rf`
(rf r x)))
;; another transducer
(defn f [rf]
(fn [r x] ; this fn itself is a reducing fn
(print "f: ") ; our contrived transformation of `rf`
(rf r x)))
;; a composite transducer
;; a fn which first calls `g` and then calls `f` with the result of calling `g`
(def h (comp f g))
;; transformed `+`; what happens when `h` gets called with `+` is:
;; 1) `g` gets called with `+` and returns a reducing fn (which prints "g: " before calling `+`)
;; 2) `f` gets called with the reducing fn retured above and then returns another reducing fn
;; (which prints "f: " before calling the argument reducing fn)
;; so the final reducing fn `+-xf`, when called, should print "f: g: " before calling `+`.
(def +-xf (h +))
;; when `+-xf` gets called
(+-xf 1 2)
;; the output will look like the following in which the order of transformations
;; (i.e., "f: " followed by "g: ") is the same as the order in which the component
;; transducers are passed to `comp` (i.e., `f` followed by `g`).
;=> f: g: 3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment