Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn lazy-multiple-filter
- "Returns a list of lazy lists, where list n will contain all the elements
- that satisfies predicate n. If an element matches more than one
- predicate, it will be placed in the list for the predicate it first matches."
- [lst & preds]
- (let [queues (take (count preds)
- (repeatedly #(ref (LinkedList.))))
- ref-lst (ref lst)
- place-elt
- (fn []
- (dosync
- (if (empty? @ref-lst)
- false
- (let [f (first @ref-lst)]
- (alter ref-lst next)
- (loop [[pred? & r-preds] preds
- [queue & r-queue] queues]
- (cond (nil? pred?)
- true
- (pred? f)
- (do
- (.offer @queue f)
- true)
- :else
- (recur r-preds r-queue)))))))]
- (map
- (fn [queue]
- ((fn fn- []
- (lazy-seq
- (dosync
- (if (.isEmpty @queue)
- (if (place-elt)
- (recur)
- nil)
- (cons (.remove @queue)
- (fn-))))))))
- queues)))
- ;; Above works fine.
- (defn lazy-multiple-filter-thread-dangerous
- "Like lazy-multiple-filter, but thread-dangerous."
- [lst & preds]
- (let [queues (take (count preds)
- (repeatedly #(LinkedList.)))
- ref-lst (atom lst)
- place-elt
- (fn []
- (if (empty? @ref-lst)
- false
- (let [f (first @ref-lst)]
- (swap! ref-lst next)
- (loop [[pred? & r-preds] preds
- [queue & r-queue] queues]
- (cond (nil? pred?)
- true
- (pred? f)
- (do
- (.offer queue f)
- true)
- :else
- (recur r-preds r-queue))))))]
- (map
- (fn [queue]
- ((fn fn- []
- (lazy-seq
- (if (.isEmpty queue)
- (if (place-elt)
- (recur)
- nil)
- (cons (.remove queue)
- (fn-)))))))
- queues)))
- ;; Above doesn't work. If you remove lazy-seq, it works completely fine.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement