评论由:cgrand 撰写
此处的提议是捕捉递归序列实现(即当尝试计算懒序列的主体时尝试访问同一序列)并抛出异常。
当前,在这种情况下发生时,对序列的递归访问将返回 nil。这导致似乎正常工作的代码产生错误结果,甚至可能出于幸运而产生正确的结果的错误代码(请参阅 https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion 中的此类示例)。
因此,这个补丁在所有可能递归调用的方法调用(.sval在.sele之前和.invoke在.sval中)之前,移动修改LazySeq状态(f, sv和s字段),以确保在重新进入时,LazySeq的状态是一致的,并且能够传达出序列已经被计算的事实。
当前,递归调用可能会发现f和sv被清除,并得出计算已完成的结论,尽管s尚未受到影响。
当前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|null|null|
|实现|空|null|任何内容|
|正在实现/从fn.invoke处递归调用|非空|null|null|
|正在实现/从ls.sval处递归调用|null|null|null|
注意,"正在实现"状态与未实现或实现重叠。
(注:"任何内容"包括null)
使用补丁
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非空|null|null|
|实现|空|null|除了这个以外的任何内容|
|正在实现|空|null|这个|