Advertisement
Guest User

Untitled

a guest
May 16th, 2012
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defn lazy-multiple-filter
  2.   "Returns a list of lazy lists, where list n will contain all the elements
  3. that satisfies predicate n. If an element matches more than one
  4. predicate, it will be placed in the list for the predicate it first matches."
  5.   [lst & preds]
  6.   (let [queues (take (count preds)
  7.                      (repeatedly #(ref (LinkedList.))))
  8.         ref-lst (ref lst)
  9.         place-elt
  10.           (fn []
  11.             (dosync
  12.               (if (empty? @ref-lst)
  13.                 false
  14.                 (let [f (first @ref-lst)]
  15.                   (alter ref-lst next)
  16.                   (loop [[pred? & r-preds] preds
  17.                          [queue & r-queue] queues]
  18.                     (cond (nil? pred?)
  19.                             true
  20.                           (pred? f)
  21.                             (do
  22.                               (.offer @queue f)
  23.                               true)
  24.                           :else
  25.                             (recur r-preds r-queue)))))))]
  26.     (map
  27.       (fn [queue]
  28.         ((fn fn- []
  29.           (lazy-seq
  30.             (dosync
  31.               (if (.isEmpty @queue)
  32.                 (if (place-elt)
  33.                   (recur)
  34.                   nil)
  35.                 (cons (.remove @queue)
  36.                       (fn-))))))))
  37.       queues)))
  38.  
  39. ;; Above works fine.
  40.  
  41.  
  42. (defn lazy-multiple-filter-thread-dangerous
  43.   "Like lazy-multiple-filter, but thread-dangerous."
  44.   [lst & preds]
  45.   (let [queues (take (count preds)
  46.                      (repeatedly #(LinkedList.)))
  47.         ref-lst (atom lst)
  48.         place-elt
  49.           (fn []
  50.             (if (empty? @ref-lst)
  51.               false
  52.               (let [f (first @ref-lst)]
  53.                 (swap! ref-lst next)
  54.                 (loop [[pred? & r-preds] preds
  55.                        [queue & r-queue] queues]
  56.                   (cond (nil? pred?)
  57.                         true
  58.                         (pred? f)
  59.                         (do
  60.                           (.offer queue f)
  61.                           true)
  62.                         :else
  63.                         (recur r-preds r-queue))))))]
  64.     (map
  65.       (fn [queue]
  66.         ((fn fn- []
  67.            (lazy-seq
  68.              (if (.isEmpty queue)
  69.                (if (place-elt)
  70.                  (recur)
  71.                  nil)
  72.                (cons (.remove queue)
  73.                      (fn-)))))))
  74.       queues)))
  75.  
  76. ;; Above doesn't work. If you remove lazy-seq, it works completely fine.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement