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

欢迎!请参阅 关于 页面以获取有关此工作的更多信息。

+2 投票
Clojure

已创建了多个工单,建议在 clojure.set 命名空间中的某些函数接收到非集合参数时可能会抛出异常,因为它们在某些情况下返回了意外的值。此列表是一个样本,并非完整列表:CLJ-810, CLJ-1682, CLJ-1953, CLJ-1954

现在 clojure.spec 存在,可以更精确地记录这些函数的预期参数类型。这些规范可以用作在测试期间动态检测传递给这些函数的错误参数类型,以及未来在 clojure.spec 上构建的其他方法。

Alex Miller 在 Slack 讨论中建议,如果贡献者能帮助在 Clojure 中的函数内实现此类规范,可能会很有帮助。

建议修补程序采用的方法是将 clojure.set/subset?、superset?、union、intersection 和 difference 的 :args 规范为必须是集合,并将前两个的 :ret 类型规范为布尔值,后三个规范为集合。这似乎符合已知反对前述更改的函数行为的所有评论。

修补程序:CLJ-2287-add-clojure-set-specs-v1.patch

在上述修补程序中未采用替代方法的是,也允许 nil 作为参数和返回值,但尚不清楚这是否是这些函数预期合同的一部分,或它们当前实现的一个附带方面。

我(Andy Fingerhut)检查了所有 Clojure 和 contrib 项目中 clojure.set/union、difference、intersection、superset? 和 subset? 的出现情况,只有一个这样的调用我无法迅速确定是否将集合传递给它。这是 clojure.data/diff 中的一个调用,此工单上有补丁可以修复此错误(假定如果这是错误):CLJ-1087

我可以迅速确定许多此类调用始终传递集合(例如,因为参数被 (set ...) 调用包装)。在这些调用中的一小部分上,我放弃了在几分钟内弄清楚答案,因为从代码检查中完全确定答案需要追溯到调用树的一定深度。

请提出其他可以评估这些变更以增加您对它们正确性的信心的方法。

7 答案

0
_评论由: alexmiller_发表

目前我会说当然。 :) 我认为这个特定的示例是一个很好的例子。

我不确定这里所有的规范都像您预期的那样明显,或者至少这是我过去在其他地方的经验。

顺便说一下,我预计这些规范将位于 clojure.set.specs 命名空间。
0

评论由: jafingerhut 发表

附件 CLJ-2287-add-clojure-set-specs-v1.patch,日期为 2017 年 12 月 13 日。这是我第一次编写 Clojure 规范,所以请随意提出改进建议。

我使用了命名空间 clojure.set.specs.alpha 而不是您建议的 clojure.set.specs,但如果您真的想让它没有 .alpha,我可以轻松更改它

0

评论由: jafingerhut 发表

如果存在某种方式我可以通过大量的测试来测试 :args 规范,请告诉我如何操作,然后我可以尝试。

显然,我在至少为 :args 和 :ret 比较明显的规范选择上做出了一些选择,我相信这是正确的,考虑到过去对那些函数的问题。我不认为它们对于这些函数可以有任何更细微之处,但请告诉我如果我在遗漏什么,例如,Clojure 核心团队决定支持这些函数的非集合参数。

我同意 clojure.set 命名空间中的一些其他函数在规范参数可能会有点棘手。

0

评论由: jafingerhut 发表

我查看过 Clojure 和 contrib 项目中 clojure.set/union、difference、intersection、superset? 和 subset? 的所有情况,只有一个我不确定的调用不将这些函数传递给集合。它是 clojure.data/diff 中的一个调用,该调用在此破损上有一个补丁,该补丁可以 '修正'这一票(假设它被视为一个错误):https://dev.clojure.org/jira/browse/CLJ-1087

我可以迅速确定许多此类调用始终传递集合(例如,因为参数被 (set ...) 调用包装)。在这些调用中的一小部分上,我放弃了在几分钟内弄清楚答案,因为从代码检查中完全确定答案需要追溯到调用树的一定深度。

0

评论由: jafingerhut 发表

如果您需要一个与 clojure.set 函数功能相同、但除了它们会对您提供的参数进行运行时类型检查并在类型错误时抛出异常(例如,对于并集、交集、差集、subset? 和 superset? 不是集合),现成的兼容替代品,请考虑使用 fungible 库:https://github.com/jafingerhut/funjible

0

评论由: jafingerhut 发表

此 Github 仓库实现了一些 Clojure 核心函数规范的思路:https://github.com/slipset/speculative

关于这个问题,有一些关于在某些测试集中所见到的 clojure.set 函数规范违反类型的讨论。我还没有看到所有数据的一个简要总结。只是想从这个问题中提供一个链接作为参考:https://github.com/slipset/speculative/issues/161

0
参考: https://clojure.atlassian.net/browse/CLJ-2287 (由 jafingerhut 报告)
...