Skip to content

Instantly share code, notes, and snippets.

@jclaggett
Created November 12, 2022 18:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jclaggett/9325f1daf88e7c455458791dfee5144e to your computer and use it in GitHub Desktop.
Save jclaggett/9325f1daf88e7c455458791dfee5144e to your computer and use it in GitHub Desktop.
demultiplex in clojure
(ns xflib)
(defn demultiplex [n]
(if (= n 1)
identity
(let [expected-result-calls* (atom n)
shared-reducer* (atom nil)
reduced-value* (atom nil)]
(fn [r]
(if-let [shared-reducer @shared-reducer*]
shared-reducer
(reset! shared-reducer*
(fn
([] (r))
([a v]
(if-let [reduced-value @reduced-value*]
reduced-value ;; return reduced value from now on
(let [a (r a v)]
(when (reduced? a)
(reset! reduced-value* a))
a)))
([a]
(if (pos? (swap! expected-result-calls* dec))
a ;; Don't call r if more expected result calls!
(r a))))))))))
(defn demo []
(let [shared-xf (comp (demultiplex 2) (take 2))
a-xf (comp (map inc) shared-xf)
b-xf (comp (map odd?) shared-xf)
a-rf (a-xf conj)
b-rf (b-xf conj)]
[(-> []
(a-rf 1)
(b-rf 2)
(unreduced)
(a-rf)
(b-rf))]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment