评论由:cgrand 提出}
此建议是在遇到递归序列实现时(即在计算惰性序列的主体时尝试访问同一序列)捕获异常并抛出异常。
目前,在这种情况下,序列的递归访问返回 nil。这导致看似正确的代码产生了错误的结果,或者错误代码可能出于偶然产生了正确的结果(参见https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion以获取此类示例)。
因此,此补丁将 LazySeq 状态(f、sv 和 s字段)的修改移动到所有潜在的递归方法调用之前(.seq 中的 .sval 和 .sval 中的 .invoke),以便在重新进入时,LazySeq的状态保持一致,并能传达序列正在被计算的事实。
目前,递归调用可能会发现 f 和 sv 已清空,并得出计算已完成并且结果已在 s 中的结论,尽管 s 还未受到影响。
目前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|null|null|
|已实现|null|null|任何内容|
|正在实现/来自 fn.invoke 的递归调用|非空|null|null|
|正在实现/来自 ls.sval 的递归调用|null|null|null|
注意,“正在实现”状态与“未实现”或“已实现”重叠。
(注意:“任何内容”包括 null)
使用补丁
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|null|null|
|已实现|null|null|除了这个之外的所有内容|
|正在实现|null|null|这个|