评论由:cgrand 撰写
此建议是捕获递归序列实现(即当计算延迟序列的主体时尝试访问相同的序列)并抛出异常。
目前,当这种情况发生时,序列的递归访问返回 nil。这导致看似正确的代码产生了错误的结果,甚至错误代码出于偶然产生了正确的结果(请参阅 https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion 以获取此类示例)。
因此,这个补丁在所有可能递归的方法调用之前(.seq中的.sval和.fn.invoke中的.sval)移动了LazySeq状态(f、sv和s字段)的修改,以确保在重新进入时,LazySeq的状态是一致的,并且可以传达序列已经被计算的事实。
目前,递归调用可能会发现f和sv被清除,并得出计算已完成且结果在s中的结论,尽管s尚未受到影响。
目前
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|不为null|null|null|
|已实现|null|null|任何东西|
|正在实现/来自fn.invoke的递归调用|不为null|null|null|
|正在实现/来自ls.sval的递归调用|null|null|null|
请注意,“正在实现”状态与未实现或已实现状态重叠。
(注:“任何东西”包括null)
有了这个补丁
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|不为null|null|null|
|已实现|null|null|但不是这个|
|正在实现|null|null|这个|