为什么`clojure.set/union`函数接受其他类型的数据作为输入?

为什么`clojure.set/union`函数接受其他类型的数据作为输入?,clojure,union,Clojure,Union,我正在学习Clojure,我发现了一些让我吃惊的事情,正如标题中提到的。如上所述,clojure.set/union函数 返回一个集,该集是输入集的并集 然而,我尝试输入其他类型的序列,它给了我一些结果,而不是告诉我输入类型是错误的。比如说 user=> (clojure.set/union '(1 2 3) '(2 3 4)) (4 3 2 1 2 3) 在这里,我希望Clojure警告我,我的输入不是集合,但它返回另一个内部有重复项的列表,这也与文档中所述的相反(“返回集合”) 我想

我正在学习Clojure,我发现了一些让我吃惊的事情,正如标题中提到的。如上所述,
clojure.set/union
函数

返回一个集,该集是输入集的并集

然而,我尝试输入其他类型的序列,它给了我一些结果,而不是告诉我输入类型是错误的。比如说

user=> (clojure.set/union '(1 2 3) '(2 3 4))
(4 3 2 1 2 3)
在这里,我希望Clojure警告我,我的输入不是集合,但它返回另一个内部有重复项的列表,这也与文档中所述的相反(“返回集合”)


我想知道为什么这个函数是这样设计的,它比给出一个类型错误有什么好处。提前谢谢

虽然我更希望看到更多的类型检查,但Clojure通常采用“垃圾输入,垃圾输出”的理念。在本例中,它扩展到,假设您为
union
函数提供了两个集合

看起来:

(defn联合
“返回作为输入集并集的集”
[s1及s2]
(如果(<(计数s1)(计数s2))
(减少conj s2 s1)
(减少conj s1 s2)))

您可以看到,它只是使用
conj
将较短的输入附加到较长的输入上。对于顺序列表或向量,这会将第二个项目列表(一次一个)添加到第一个列表的前面,如您的示例所示。

谢谢@Alan!源代码解释了其行为的一切。虽然我认为在列表输入中获得更合理的回报应该是个例外。是的,我也是。或者,至少,先强制进入一个集合。
(defn union
  "Return a set that is the union of the input sets"
  [s1 s2]
     (if (< (count s1) (count s2))
       (reduce conj s2 s1)
       (reduce conj s1 s2)))