请在 2024 年 Clojure 状态调查 中分享您的想法!

欢迎!请参阅 关于 页面,了解有关此功能的一些更多信息。

+6
Clojure
已关闭

当使用 some-fn 和 3 个谓词时,其递归评估顺序不同,some-fn 的短路行为也不同

使用 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-arity 的行为符合这一点。

可能的解决方案
我认为这需要修正文档字符串,将 "第一个参数" 替换为 "一个参数"。为了使短路行为一致,修补可能是一个破坏性改变,因为可能会返回可能不同的逻辑真值。

此外,此文档字符串行与 "every-pred" 相同,"every-pred" 在其 3 个谓词阶数与 2 个和更多阶数之间具有相同的不同评估顺序和短路行为。与 "every-pred" 的这种影响的较小是因为 every-pred 只返回布尔真或假,而 "some-fn" 返回逻辑真值。

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

2 回答

0

当有4个或更多的谓词时,策略会发生变化。不再是按照顺序测试 (p1 x), (p2 x), (p1 y), (p2 y) 等等,而是切换到 (p1 x), (p1 y), (p2 x), (p2 y) ...

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

3个谓词的版本是对每个谓词分别针对arg1进行测试,然后分别针对arg2进行测试,然后分别针对arg3进行测试,等等。2个和4个以上谓词的版本是先对pred1针对每个arg进行测试,然后对pred2针对每个arg进行测试,然后对pred3针对每个arg进行测试,等等。我认为docstring可以按这两种方式阅读(在我看来),但对于非3个谓词的版本,实际上它会在第一个在任一arg上为true的_predicte_结束时停止。所以我认为3个谓词的版本是“错误的”,并且docstring有点误导。
0
...