已创建了多个工单,建议在 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 ...) 调用包装)。在这些调用中的一小部分上,我放弃了在几分钟内弄清楚答案,因为从代码检查中完全确定答案需要追溯到调用树的一定深度。
请提出其他可以评估这些变更以增加您对它们正确性的信心的方法。