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

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

+2
Clojure

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

由于 clojure.spec 存在,可以更精确地记录这些函数的预期参数类型。这些规范可以在测试期间动态检测传递给这些函数的错误参数类型,并可以通过任何基于 clojure.spec 构建的其他方式future。

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函数(在行为上相同,但它们会对您提供的参数执行运行时类型检查,如果类型错误则抛出异常,例如,不适用于并集、交集、差集、子集?和超集?),请考虑使用可通用的库: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报告)
...