2016-06-09 59 views
3

我只是在學習語言,我有一個簡單的問題。爲什麼這項工作(構建{:key "value"}):在Clojure的匿名函數上構建地圖

(#(assoc {} :key %) "value") 

但這並不:

(#({:key %}) "value") 
ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:429) 

關於Python後者的語法是完全有效:

> (lambda v: {'key': v})('value') 
{'key': 'value'} 

編輯:感謝偉大的答案,很明顯我需要停止在Python中認爲#等於lambda

+1

'#(f x)==(fn [](f x)):。 #({x})==(fn []({x}))' – dsm

+1

這是一個簡單的hacky,但是如果你想從anon fn返回一個元素:'#( - > {:key%})' – ClojureMostly

+1

還有'#(散列圖:k%)' – cfrick

回答

3

#(f %)由讀者擴大到​​。同樣,#({:key %})擴展爲(fn [%] ({:key %})。相當於這個python的將是lambda v: {'key': v}(),它具有與Clojure版本完全相同的問題。

你在找什麼等於(fn [v] {:key v})。如果您確實想要使用#(...)表示法,則可以使用#(do {:key %})

順便說一句,我個人從未使用#(...)。我認爲這樣做比較困難(例如這種證據),並且只比等效的fn表格更緊湊。然後還有#(...)表單不能嵌套的限制。

0

{:key %}是一個PersistentArrayMap。你可以在函數調用的「動詞位置」中找到它。你需要一種類型的Clojure方法來避免這個錯誤,正如你在第一個(工作)例子中看到的那樣。

2

這是#()閱讀器的限制。 fn將正常工作。

user=> ((fn [x] {:key x}) "value") 
{:key "value"} 

請看看文檔Anonymous function literal (#())

+0

你指的是什麼限制?我從您發佈的鏈接看到的唯一限制是「#()表單不能嵌套。」但這並不適用於這種情況...... –

+2

根據文檔,'#(...)'將被轉換爲'(fn [args](...))'。因此'#({:key%})'將被轉換爲'(fn [x]({:key x}))''。這將導致錯誤,因爲'{:key x}'處於功能位置並且沒有意義。 – ntalbs