请分享你的观点,参加 2024 Clojure 状态调查!

欢迎!有关如何使用本站的更多信息,请参阅关于页面。

+6
Clojure
已关闭

当使用 some-fn 与 3 个谓词一起使用时,其评估顺序不同,并且 some-fn 在使用 2 个谓词、3 个谓词、以及 4 个或更多谓词时的短路方式也不同。

使用 2 个谓词

((some-fn #{42} #{1}) 1 42)
=> 42

使用 3 个谓词

((some-fn #{42} #{1} :third-pred) 1 42)
=> 1

使用 4 个或更多谓词

((some-fn #{42} #{1} :third-pred :fourth+more-pred) 1 42)
=> 42

some-fn 的文档字符串说明:".... 注意:f[由 some-fn 返回的函数] 是短路的,即它会停止执行,当第一个参数触发对原始谓词的逻辑真结果时。"
我理解为只有当前 3 参数的行为符合这一点。

可能的解决方案
我认为这需要对文档字符串进行修改,将“第一个参数”替换为“一个参数”。由于可能返回不同的逻辑真值,这个补丁可能会是一个破坏性更改,导致短路方式的一致性。

此外,这条文档字符串与“every-pred”中的一致,而“every-pred”在其 3 参数与 2 和 4 个以上参数的短路评估顺序和短路行为上具有相同的差异。由于“every-pred”只返回布尔值真或假,而“some-fn”返回逻辑真值,因此这种影响较小。

关闭时的备注:已修复在 1.11.0-alpha2 中

2 个答案

0
by

当存在4个或更多谓词时,策略会发生改变。不再是按照 (p1 x), (p2 x), (p1 y), (p2 y) 等顺序进行测试,而是改为 (p1 x), (p1 y), (p2 x), (p2 y) ...

这种不一致性让我感觉像是一个bug。

by
3-谓词版本会检查每个谓词与arg1,然后每个与arg2,然后每个与arg3等。2-和4+谓词版本会先检查pred1与每个arg,然后pred2与每个arg,然后pred3与每个arg等。文档字符串可以从任一角度阅读(在我看来),但对于非3-谓词版本,实际上它会在第一个在任一arg上为真值的_predicate_处停止。因此,我认为3-谓词版本是“错误的”,而且文档字符串有点误导。
0
by
...