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函数的现成兼容替代品,这些函数除了对他们提供的参数执行运行时类型检查并在类型错误时抛出异常之外,您可以考虑使用Funjible库:https://github.com/jafingerhut/funjible

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