On Mon, Dec 8, 2008 at 6:51 PM, Rich Hickey <richhic...@gmail.com> wrote: I don't have the latest build of Clojure with atoms, so I reimplemented Rich's filter solution using refs, turning:
> (defn filter > [pred coll] > (let [sa (atom (seq coll)) > step (fn step [] > (when-let [s @sa] > (let [x (first s)] > (if (pred x) > (lazy-cons x (do (swap! sa rest) (step))) > (do (swap! sa rest) > (recur))))))] > (step))) > into: (defn safe-filter [pred coll] (let [sa (ref (seq coll)), step (fn step [] (when-let [s @sa] (let [x (first s)] (if (pred x) (lazy-cons x (do (dosync (ref-set sa (rest s))) (step))) (do (dosync (ref-set sa (rest s))) (recur))))))] (step))) But splode still splodes!: (defn splode [n] (doseq [i (safe-filter #(= % 20) (map inc (range n)))])) Any idea why the ref version wouldn't be working? > But it's not pretty. Fortunately, this segues with work I have been > doing on I/O and generators/streams. I'm really looking forward to seeing how this all turns out. Cached lazy sequences seems to be a bad default for all the standard sequence operations. You have to be very careful to not retain the head of one of these sequences (can't give names to intermediate results, for example), and it's very hard to predict when the head of one of these sequences might be unintentionally held. This seems to make code more brittle. Probably the best solution is to default to sequences that always freshly generate the results, and you have to intentionally cache the sequence if that is what you want. Mark --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---