Skip to content

Instantly share code, notes, and snippets.

@cgrand cgrand/reducticons.clj
Last active Aug 29, 2015

Embed
What would you like to do?
; discussed here https://groups.google.com/d/msg/clojure-dev/cWzMS_qqgcM/7IAhzMKzVigJ
; nested reduced
=> (transduce (comp (take 1)) conj [:a])
[:a]
=> (transduce (comp (take 1) (take 1)) conj [:a])
#<Reduced@65979031: [:a]>
=> (transduce (comp (take 1) (take 1) (take 1)) conj [:a])
#<Reduced@fcbc8d1: #<Reduced@60bea99a: [:a]>>
=> (transduce (comp (take 1) (take 1) (take 1) (take 1)) conj [:a])
#<Reduced@6e9915bb: #<Reduced@5c712302: #<Reduced@472b9f70: [:a]>>>
; problems not appearing in all contexts
; ko with transduce
=> (transduce (comp (partition-by keyword?) (take 1)) conj [] [:a])
#<Reduced@5156c42e: [[:a]]>
; but ok with sequence
=> (sequence (comp (partition-by keyword?) (take 1)) [:a])
([:a])
; well, not always
=> (sequence (comp (partition-by keyword?) (take 1) (partition-by keyword?) (take 1)) [:a])
ClassCastException clojure.lang.Reduced cannot be cast to clojure.lang.LazyTransformer clojure.lang.LazyTransformer$Stepper$1.invoke (LazyTransformer.java:104)
(defn take
"Returns a lazy sequence of the first n items in coll, or all items if
there are fewer than n. Returns a stateful transducer when
no collection is provided."
{:added "1.0"
:static true}
([n]
(fn [f1]
(let [nv (volatile! n)]
(fn
([] (f1))
([result] (f1 result))
([result input]
(let [n @nv
nn (vswap! nv dec)
result (if (pos? n)
(f1 result input)
result)]
(if (or (pos? nn) (reduced? result)) ; fix
result
(reduced result))))))))
([n coll]
(lazy-seq
(when (pos? n)
(when-let [s (seq coll)]
(cons (first s) (take (dec n) (rest s))))))))
(defn partition-by
"Applies f to each value in coll, splitting it each time f returns a
new value. Returns a lazy seq of partitions. Returns a stateful
transducer when no collection is provided."
{:added "1.2"
:static true}
([f]
(fn [f1]
(let [a (java.util.ArrayList.)
pv (volatile! ::none)]
(fn
([] (f1))
([result]
(let [result (if (.isEmpty a)
result
(let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(f1 result v)))
result (if (reduced? result) @result result)] ; fix
(f1 result)))
([result input]
(let [pval @pv
val (f input)]
(vreset! pv val)
(if (or (identical? pval ::none)
(= val pval))
(do
(.add a input)
result)
(let [v (vec (.toArray a))]
(.clear a)
(let [ret (f1 result v)]
(when-not (reduced? ret)
(.add a input))
ret)))))))))
([f coll]
(lazy-seq
(when-let [s (seq coll)]
(let [fst (first s)
fv (f fst)
run (cons fst (take-while #(= fv (f %)) (next s)))]
(cons run (partition-by f (seq (drop (count run) s)))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.