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

欢迎!有关如何操作的更多信息,请参阅关于页面。

0
Collections

clojure.set/union 对其输入的类型非常敏感。它不会尝试检查或修复输入类型,也不会引发错误或记录这种行为。

如果所有输入都是集合,则它将正常工作。

`
ti.repl-init=> (clojure.set/union #{1 2 3} #{1 2 3 4})

{1 4 3 2}

`

如果参数都是向量或序列,则返回相同类型,包含重复项。

ti.repl-init=> (clojure.set/union [1 2 3] [1 2 3]) [1 2 3 1 2 3] ti.repl-init=> (clojure.set/union (list 1 2 3) (list 1 2 3)) (3 2 1 1 2 3)

如果参数是混合的,只有在最长的输入参数是集合的情况下才会返回正确的结果。

`
ti.repl-init=> (clojure.set/union #{1 2 3} [2 3])

{1 3 2}

ti.repl-init=> (clojure.set/union [1 2 3] #{2 3})
[1 2 3 3 2]
ti.repl-init=> (clojure.set/union [2 3] #{1 2 3})

{1 3 2}

ti.repl-init=> (clojure.set/union #{2 3} [1 2 3])
[1 2 3 3 2]
`

5 个回答

0

评论由:alexmiller

这一问题已被多次提出。请参阅 CLJ-1682,CLJ-810。

0

评论由:ashtonkemerling

我未在您提到的票中看到对 set/union 的说明。

此外,此问题在某些重要的方面与交集错误有所不同

  1. 它静默地返回错误的类型和包含错误值的数据。
  2. 它永远不会引发异常。

但它确实与交集问题共享以下错误:

  1. 这种行为不仅与类型相关,也与数据相关。它会根据给定集合的长度而工作。
  2. 甚至没有文档说明此函数期望集合。
  3. 这直接违反了它所声称表示的数学函数的定义。

我只是在检查结果时发现了这个错误,我本来以为集合/并集会做正确的事,但是出乎意料的是,它既不符合定义也不符合文档。

0

评论者:jafingerhut

阿什顿,我对你的愿望表示同情,但没有新论据可能说服那些决定将更改应用到Clojure的人,这确实是个好主意。

我想指出你对一个评论的回答:“甚至没有文档说明此函数期望集合。”在我看来,从过去的评论中可以看出,Clojure核心团队的观点是,这确实是文档化的,例如,“返回一个输入集合的并集的集合”告诉你当给clojure.set/union提供集合作为参数时,它做什么。它对当你提供非集合参数时它做什么没有指定任何内容,所以它可以对这些情况做任何事,包括它目前所做的任何事情。

0

评论者:jafingerhut

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

0
参考:[https://clojure.atlassian.net/browse/CLJ-1953](https://clojure.atlassian.net/browse/CLJ-1953) (由 alex+import 报告)
...