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

Reply via email to