评论由:cgrand 撰写
这个提议是要捕获递归的 seq 实现过程(即当计算 lazy-seq 的主体时尝试访问同一个 seq)并抛出异常。
目前,当发生此类情况时,递归访问 seq 返回 nil。这导致看似正确但产生错误结果的代码或在幸运的情况下产生正确结果的错误代码(请参阅https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion中的此类示例)。
因此,这个修补程序将先修改 LazySeq 状态(f、sv 和 s 字段),然后调用所有可能递归的方法调用(.seq 中的 .sval 和 .sval 中的 .invoke),以便在重新进入时,LazySeq 的状态是一致的,并能传达该 seq 已经正在被计算的事实。
目前递归调用可能会发现 f 和 sv 已清除,并得出结论,计算已完成,且结果在 s 中,尽管 s 尚未受到影响。
目前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|空|空|
|已实现|空|空|任何值|
|正在实现/从 fn.invoke 调用的递归调用|非空|空|空|
|正在实现/从 ls.sval 调用的递归调用|空|空|空|
注意,“正在实现”与“未实现”或“已实现”状态重叠。
(注意:“任何值”包括空)
应用补丁
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|空|空|
|已实现|空|空|除这个以外的任何值|
|正在实现|空|空|这个值|