在类似于(do (for (link: x (do (println "realized") nil)) x) nil)的调用中,for理解表达式永远不会请求任何元素,因此实际上并不需要评估内部的do块。然而,这个表达式导致“realized”被打印出来,因为即使在输出惰性序列中从未请求过任何项目,for中的第一个序列表达式仍然会被评估。
文档中没有说明这是故意还是无意为之,但我对这个行为感到惊讶,以及在#clojure上的简短非科学的调查表明,其他用户,甚至是使用clojure多年的“老手”也不期望这种行为。
我附上了一个补丁,该补丁是用惰性序列调用包装有问题表达式。这并不是最佳方案,因为它意味着第一次迭代会被“惰化”两次,就像((fn step (link: s) (lazy-seq ...)) (lazy-seq xs))那样,但进行这一更改的范围会更广,这似乎是最少危险的。