当序列体包含宏并抛出异常时,lazy-seq 似乎会不一致地进行评估。第一次评估抛出异常,随后的评估返回空序列。
演示代码
`
(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)))
`
它应该两次都抛出异常,但只发生在第一次。一般而言,一个表达式不应该根据其是否已经被评估过而有不同的结果。
当移除闭包 ...
`
(defn gen-lazy []
(lazy-seq
(when-let [s (seq [1 2 3])]
(throw (Exception.)))))
`
... 或移除 when-let 宏 ...
`
(defn gen-lazy []
(let [coll [1 2 3]]
(lazy-seq
(seq coll)
(throw (Exception.)))))
`
它就会工作,即一致地抛出异常,所以这表明闭包和宏之间可能存在某种交互。这种特定的组合用于 'map' 函数中。
另请参阅:[https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z3EiBUQ7Inc](https://groups.google.com/forum/?fromgroups=#!topic/clojure/Z3EiBUQ7Inc)