Skip to content

Instantly share code, notes, and snippets.

@cgrand
Created October 10, 2014 14:46
Show Gist options
  • Save cgrand/ad01fd16fd8f8d1ab9b5 to your computer and use it in GitHub Desktop.
Save cgrand/ad01fd16fd8f8d1ab9b5 to your computer and use it in GitHub Desktop.
(ns mutabots)
(defn map [f]
(fn [p1]
(fn
([] (p1))
([x] (p1 (f x))))))
(defn filter [pred]
(fn [p1]
(fn
([] (p1))
([x] (and (pred x) (p1 x))))))
(defn take [n]
(fn [p1]
(let [vn (volatile! (dec n))]
(fn
([] (p1))
([x] (or (neg? @vn) (p1 x) (neg? (vswap! vn dec))))))))
(defn partition-by [f]
(fn [p]
(let [a (java.util.ArrayList.)
pv (volatile! ::none)]
(fn
([]
(when-not (.isEmpty a)
(let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(p v)))
(p))
([input]
(let [pval @pv
val (f input)]
(vreset! pv val)
(if (or (identical? pval ::none)
(= val pval))
(do (.add a input) false) ; .add returns true
(let [v (vec (.toArray a))]
(.clear a)
(or (p v)
(do (.add a input) false))))))))))
(defn transduce [xform f init coll]
(let [vres (volatile! init)
p (fn
([] (vswap! vres f))
([x] (let [res (f @vres x)
done (reduced? res)]
(vreset! vres (if done @res res))
done)))
p (xform p)]
(reduce (fn [_ x] (when (p x) (reduced nil))) coll)
@vres))
;; bleh :-(
(defn- promised-seq-proc! [pstep! p]
(let [vp (volatile! p)]
(fn
([]
(deliver @vp nil))
([x]
(deliver @vp (cons x (let [p (vreset! vp (promise))]
(lazy-seq (@pstep! p) @p))))
false))))
(defn sequence [xform coll]
(let [vcoll (volatile! coll)
p (promise)
promised-seq (lazy-seq p)
pstep! (promise)
proc! (xform (promised-seq-proc! pstep! p))
step! (fn [p]
(loop [coll @vcoll]
(if (realized? p)
(vreset! vcoll coll)
(if-let [[x :as s] (seq coll)]
(recur (if (proc! x) nil (rest s)))
(proc!)))))]
(deliver pstep! step!) ; tying the knot
(lazy-seq (step! p) @p)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment