评论由:cgrand 添加
此提议是捕获递归序列实现(即当在计算惰性序列的具象时尝试访问同一序列时)并抛出异常。
目前,在这种情况下,对序列的递归访问返回空值。这导致代码看似正确运行,但产生不正确的结果,甚至可能由于机会而导致正确的结果(请参阅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
| :-- | :-- | :-- | :-- | :-- |
未实现 | 不为空 | 空值 | 空值
已实现 | 空值 | 空值 | 任何值
正在实现/由fn.invoke触发的递归调用 | 不为空 | 空值 | 空值
正在实现/由ls.sval触发的递归调用 | 空值 | 空值 | 空值
注意,"正在实现"的状态与"未实现"或"已实现"重叠。
(NB:"任何值"包括空值)
使用该补丁
状态 | f | sv | s
| :-- | :-- | :-- | :-- | :-- |
未实现 | 不为空 | 空值 | 空值
已实现 | 空值 | 空值 | 除了这个以外的任何值
正在实现 | 空值 | 空值 | 这个