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. 这与它所声称表示的数学函数的定义正好相反。

我只在自己的代码中发现了这个错误,因为手动检查了结果。我只是假设集合/并集会做正确的事情,但发现它既不符合定义也不符合文档,这让我非常惊讶。

0

评论者:jafingerhut

我同情你的愿望,Ashton,但我没有能够说服决定对Clojure进行更改的人的新论据,使其成为一件值得做的事情。

我想谈谈你对你的评论之一的回答:“甚至没有文档说明这个函数期望集合。”在我看来,从以前的评论中可以推断出Clojure核心团队的观点是,这一点确实已经说明白了,例如,“返回一个并集的集合”告诉你当给clojure.set/union传递集合作为参数时它做什么。它对当给你传递非集合参数时不做什么没有明确说明,所以它在这些情况下可以做任何它想做的事情,包括它目前正在做的事。

0

评论者:jafingerhut

如果您想要一个现成的与clojure.set函数行为相同但具有运行时类型检查功能的替代品(如果它们提供错误类型,则引发异常,例如对于并集,交集,差集,子集?和超集?不是集合),请考虑使用可替换库:https://github.com/jafingerhut/funjible

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