在clojure中,为什么assoc除了地图之外还需要参数,但不是?

时间:2013-04-23 16:53:13

标签: clojure

在clojure中,

(assoc {})

引发了一个arity异常,但是

(dissoc {})

没有。为什么?我希望他们俩都抛出异常,或者两者都没有在没有提供密钥或值的情况下做出任何改变。

编辑:我看到允许这些表格的理由;这意味着我们可以将assoc或dissoc应用于可能为空的参数列表。我只是不明白为什么一个人会被允许而另一个不被允许,我很好奇是否有一个很好的理由让我失踪。

2 个答案:

答案 0 :(得分:4)

我个人认为缺少1-arity assoc是一种疏忽:每当有一个参数的尾随列表(& stuff)时,该函数通常应该能够使用零参数来实现它将apply改为空列表。

Clojure还有许多其他函数可以正确地使用零参数,例如: +merge

另一方面,Clojure还有其他功能接受零尾随参数,例如: conj

所以Clojure API在这方面有点不一致.....

答案 1 :(得分:0)

这不是一个权威的答案,而是基于我的测试并查看ClojureDocs:

dissoc的arity包括你能够传递一个参数,一张地图。在这种情况下,没有键/值从地图中删除。

(def test-map {:account-no 12345678 :lname "Jones" :fnam "Fred"})
(dissoc test-map)
{:account-no 12345678, :lname "Jones", :fnam "Fred"}

assoc没有类似的arity。那就是调用assoc需要一个map,key和value。

现在为什么这样设计是另一回事,如果你没有收到有关这些信息的答案 - 我希望你这样做 - 那么我建议你提供赏金或者继续使用Clojure的Google网上论坛并提出这个问题

这是来源。

(defn dissoc
  "dissoc[iate]. Returns a new map of the same (hashed/sorted) type,
that does not contain a mapping for key(s)."
  {:added "1.0"
   :static true}
  ([map] map)
  ([map key]
   (. clojure.lang.RT (dissoc map key)))
  ([map key & ks]
   (let [ret (dissoc map key)]
     (if ks
       (recur ret (first ks) (next ks))
       ret))))