请在 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函数行为完全一致的兼容替代品,但它们除了提供运行时类型检查之外,还有错误类型时抛出异常(例如,对于并集、交集、差集、子集?和超集?,不是集合),请考虑使用 fungible 库: https://github.com/jafingerhut/funjible

0

评论者:jafingerhut

此Github仓库实现了对Clojure核心函数的一些规格化的想法: https://github.com/slipset/speculative

有关某些collections测试中观察到的clojure.set函数规格违反情况的一些讨论。我尚未看到对所有数据的简要总结。只是想要从该问题获取链接作为参考:https://github.com/slipset/speculative/issues/161

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