评论者:cgrand
在此提议中,将捕获递归序列实现(即当尝试计算lazy-seq的主体时访问相同的序列)并抛出异常。
当前在这种情况下,递归访问序列返回nil。这导致看似工作但产生错误结果的代码,或者偶然产生正确结果的错误代码(请参阅https://groups.google.com/d/topic/clojure/yD941fIxhyE/discussion中的此类示例)。
因此,这个补丁在所有可能的递归方法调用之前(.seq中的.fval和.sval中的.invoke)修改了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|
请注意,“已实现”的状态与未实现或实现的状态有重叠。
(注:“任何事物”包括空值)
随着补丁
|状态|f|sv|s|
| :-- | :-- | :-- | :-- | :-- |
|未实现|非null|null|null|
|已实现|空值|空值|除了这个以外的任何事物|
|正在实现|空值|空值|这个|