This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-09
Channels
- # aws (1)
- # babashka (61)
- # bangalore-clj (5)
- # beginners (83)
- # biff (2)
- # calva (4)
- # cider (6)
- # clara (5)
- # clj-kondo (72)
- # cljs-dev (31)
- # cljsrn (28)
- # clojure (8)
- # clojure-australia (1)
- # clojure-europe (19)
- # clojure-france (1)
- # clojure-losangeles (21)
- # clojure-nl (2)
- # clojure-spec (2)
- # clojure-uk (9)
- # clojurescript (13)
- # clojureverse-ops (5)
- # code-reviews (1)
- # conjure (7)
- # cursive (4)
- # datascript (2)
- # datomic (8)
- # depstar (1)
- # emacs (3)
- # etaoin (1)
- # events (3)
- # exercism (7)
- # fulcro (6)
- # girouette (2)
- # graalvm (125)
- # honeysql (19)
- # integrant (1)
- # jobs (12)
- # lsp (1)
- # numerical-computing (1)
- # off-topic (23)
- # portal (12)
- # practicalli (1)
- # re-frame (35)
- # reitit (5)
- # releases (1)
- # remote-jobs (1)
- # shadow-cljs (51)
- # tools-deps (14)
- # vim (3)
- # xtdb (20)
Thoughts on this:
A "higher order transducer" capture
which takes a transducer, a reducing function and an init function of one argument.
It essentially wraps a transducer and captures all output from it, collecting it according to reducef
and initf
(applied to the first x it receives).
This guarantees that you will get one output for every input passed through the transducer. This is useful for working with tabular data, where you want to use a transducer to "append a column" (example comping soon).
I'm most uncertain about the arity of initf
or if it should even be a function at all. It tended to be useful in practice but it seems inelegant in a way vs the traditional reduce signature.
I'm also wondering if there are any edge cases I've missed, especially surrounding reduced
(defn capture
([xf] (capture xf conj))
([xf reducef] (capture xf reducef (constantly (reducef))))
([xf reducef initf]
(fn [rf]
(let [a (volatile! [])
collect! (fn [_acc x]
(vswap! a reducef x))
init! (fn [x] (vreset! a (initf x)))
f (xf collect!)
handle-input (fn [acc x]
(init! x)
(f a x)
(rf acc (unreduced @a)))]
(fn
([] (rf))
([acc] (rf acc))
([acc x]
(handle-input acc x)))))))
(comment
(into []
(capture (partition-all 2))
(range 5))
;;=> [[] [[0 1]] [] [[2 3]] []]
(into []
(capture (dedupe)
(fn [acc x]
(reduced (if (some? x) x :na)))
(fn [x] :na))
[1 2 2 3 4 5 5 6])
;; [1 2 :na 3 4 5 :na 6]
(into []
(capture (mapcat :x))
[{:x (range 10)}
{:x (range 2)}])
;;[[0 1 2 3 4 5 6 7 8 9] [0 1]]
(into []
(capture
(mapcat :x)
(fn [acc x] (when x (reduced x)))
(constantly nil))
[{:x (range 10)}
{:x (range 2)}])
;;[0 0]
)