2013-04-23 55 views
8

Clojure中,在clojure中,爲什麼assoc除了地圖之外還需要參數,但解碼不是?

(assoc {}) 

拋出元數異常,但

(dissoc {}) 

沒有。爲什麼?如果沒有提供鍵或值,我會希望它們兩個都拋出異常,或兩者都不作任何更改。

編輯:我看到允許這些形式的基本原理;這意味着我們可以將assoc或dissoc應用於可能爲空的參數列表。我只是不明白爲什麼一個人會被允許,而另一個人不會,而且我很好奇這是否有一個很好的原因,我錯過了。

+0

'(assoc {})'沒有任何意義,因此它是不允許的。 – dsm 2013-04-23 18:01:55

+1

請注意'(dissoc {})'也不是。 – dsm 2013-04-23 18:09:16

+3

我的觀點是,兩者都有意義,或者兩者都沒有意義;但一個是允許的,另一個不是(至少在clojure 1.5.1上)。我很好奇爲什麼。 – 2013-04-23 18:23:29

回答

4

我個人認爲缺少1元數副教授是一個監督:每當參數尾隨名單預計(& stuff),功能一般應能夠與零個參數,以便使其能夠工作到apply它到一個空的列表。

Clojure有很多其他函數可以用零參數正確工作,例如, +merge。另一方面,Clojure具有不會接受零尾隨參數的其他功能,例如, conj

所以Clojure API在這方面有點不一致.....

0

這不是一個權威的答案,但根據我的測試,看着ClojureDocs:

dissoc的元數包括你能在一個參數,一個地圖通過。在這種情況下,沒有鍵/值從地圖上移除。

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

assoc沒有類似的arity。這是調用assoc需要一個地圖,關鍵和值。

現在爲什麼用這種方式設計這是另一回事,如果您沒有收到有關這些信息的答案 - 我希望您能這樣做 - 那麼我建議您提供賞金或者去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)))) 
+0

我不會將此添加到我的答案中,因爲這是一個有教養的猜測。看起來,其中一個用於部分函數和Thrush操作符。這是一個(dissoc test-map)可能被編入一個表單,最終包含一個要刪除的鍵。但是,這是一個有教養的猜測,我希望Clojure知識淵博的人會回答。 – octopusgrabbus 2013-04-23 20:05:36

相關問題