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

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

+2
Clojure jira

已经创建了几个工单,建议在 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](https://dev.clojure.org/jira/browse/CLJ-1087)

我迅速确定许多这样的调用始终传递集合(例如,因为参数被包装在 (set ...) 调用中)。在很小一部分中,我放弃了在一分钟内找到答案,因为从代码检查中完全确定答案需要回溯调用树一段距离。

0

由 jafingerhut 评论:

如果您需要clojure.set函数的现成兼容替代品,其行为相同,除了它们在运行时检查您提供的参数的类型,并且如果类型不正确(例如,联合、交集、差集、子集?和上集合?不是集)则抛出异常,请考虑使用 fungible 库:[https://github.com/jafingerhut/funjible](https://github.com/jafingerhut/funjible)

0

由 jafingerhut 评论:

此Github仓库实现了一些关于Clojure核心函数规格的想法:[https://github.com/slipset/speculative](https://github.com/slipset/speculative)

关于这个问题的一些讨论,讨论了在某些测试集合中看到的某些clojure.set函数规格违规的类型。我还没有看到所有数据的简要总结。只想从这个问题中有一个链接以供参考:[https://github.com/slipset/speculative/issues/161](https://github.com/slipset/speculative/issues/161)

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