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

欢迎!请参阅关于页面,了解更多关于此功能的信息。

0 投票
集合

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. 这与它所声称代表的最基本的数学函数的定义完全相反。

我仅通过手动检查结果,才发现我自己的代码中存在这个bug。我本来以为集合/并集操作能够正确执行,但是当结果与定义和文档相反时,我深感惊讶。

0 投票

评论者:jafingerhut

我对您的愿望表示同情,阿什顿,但没有任何新颖的论据能够说服决定对Clojure做什么改变的人,认为这是一件好事。

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

0 投票

评论者:jafingerhut

如果您想寻找一个现成的,与clojure.set函数在行为上相同,除了它们对提供的参数执行运行时类型检查并在类型错误时抛出异常之外(例如,对于并集、交集、差集、子集?和超集?不是集合),请考虑使用 fungible 库: https://github.com/jafingerhut/funjible

0 投票
参考资料:https://clojure.atlassian.net/browse/CLJ-1953(由alex+import报告)
...