评论者:cgrand
此提议是捕获递归序列实现(即在计算延迟序列的主体时尝试访问相同的序列)并抛出异常。
目前,在这种情况下,序列的递归访问返回nil。这导致看似正确的代码产生不正确的结果,甚至偶然产生正确结果的不正确代码(参见https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion中的此类示例)。
因此,此补丁将修改LazySeq状态的更改(f, sv和s字段)放在所有可能的递归方法调用(在.seq的循环中和.sval中的.Invoke)之前,以便在重新进入时,LazySeq的状态是一致的并能够传达该序列已被计算的事实。
目前递归调用可能会发现 f 和 sv 已清除,并得出计算已完成且结果在 s 中的结论,尽管 s 目前未受到影响。
目前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空null|null|
|已实现|null|null|任何东西|
|正在实现/从 fn.invoke 的递归调用|非空null|null|null|
|正在实现/从 ls.sval 的递归调用|null|null|null|
注意,“正在实现”状态与“未实现”或“已实现”状态重叠。
(NB:“任何东西”包括 null)
补丁后
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空null|null|
|已实现|null|null|这个之外的所有东西|
|正在实现|null|null|这个|