由 cgrand 发布的评论
这里提出的建议是捕获递归序列实现(即当尝试计算懒序列的主体并访问同一序列时)并抛出异常。
目前,在发生这种情况时,递归访问序列返回 nil。这导致看似正常工作的代码产生错误的结果,甚至可能是错误代码在没有错误结果的情况下产生了正确的输出(参见https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion的示例)。
因此,此修补程序在所有可能递归的方法调用(.seq中的.while循环中的.sval和.sval中的.invoke)之前对LazySeq状态(f、sv和s字段)进行修改,以便在重入时,LazySeq的状态是连贯的,并且能够表达该序列已经被计算的事实。
目前,递归调用可能会发现f和sv被清除,并得出计算已完成且结果在s中的结论,尽管s尚未受到影响。
目前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
未实现|非空|空|空|
已实现|空|空|任何|
正在实现/从fn.invoke进行递归调用|非空|空|空|
正在实现/从ls.sval进行递归调用|空|空|空|
注意,“正在实现”与“未实现”或“已实现”的状态重叠。
(注意:“任何”包括空值)
使用补丁后
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
未实现|非空|空|空|
已实现|空|空|除了这个之外任何|
正在实现|空|空|这个|