2016-06-09 50 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