I've got this narrowed down to what seems an interaction issue between macros and closures in lazy-seq. Run this code:
(defn gen-lazy [] (let [coll [1 2 3]] (lazy-seq (when-let [s (seq coll)] (throw (Exception.)) ) ) ) ) (def lazy (gen-lazy)) (try (println "lazy:" lazy) (catch Exception ex (println ex)) ) (try (println "lazy, again:" lazy) (catch Exception ex (println ex)) ) ... and explain to me what you see there. The first time, exception, the second time, empty list. Now if you either a) remove the let statement and put the sequence [1 2 3] directly into where it says coll then it "works" = same exception in both cases. (defn gen-lazy [] (lazy-seq (when-let [s (seq [1 2 3])] (throw (Exception.)) ) ) ) Or if you take out the when-let macro it works, too: (defn gen-lazy [] (let [coll [1 2 3]] (lazy-seq (seq coll) (throw (Exception.)) ) ) ) Only the combination of closure + when-let macro breaks thigs. I know clojure does some funky things to closures in lazy-seq (see "... perform closed-over local clearing on the tail call of their body" on this page: http://clojure.org/lazy), this is related to the undocumented :once keyword on function calls. Maybe that interferes with macros? Or maybe I'm barking up the wrong tree. -- hank On Monday, 3 December 2012 00:58:08 UTC+11, Hank wrote: > > I'm mapping a function that throws an exception over a collection: > > => (def mapped (map (fn [_] (throw (Exception.))) [1 2 3])) > #'user/mapped > > 'map' is lazy so we're not expecting to see the exception until we're > trying to access the result: > => mapped > Exception user/fn--709 (NO_SOURCE_FILE:1) > > All good, let's do that again: > => mapped > () > > Whoops! Is this by design? Why? Where does that empty sequence come from? > > 'map' is really just calling the lazy-seq macro but doing this with lazy > seq works just fine: > => (def lazy (lazy-seq (throw (Exception.)))) > #'user/lazy > => lazy > Exception user/fn--733 (NO_SOURCE_FILE:1) > => lazy > Exception user/fn--733 (NO_SOURCE_FILE:1) > > Same exception over and over again as it should be. I stared at the > implementations of 'map' and lazy-seq/LazySeq for some hours but I really > can't see it. > > Cheers > -- hank > > -- 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 Note that posts from new members are moderated - please be patient with your first post. 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