((#(%a %b') {a:1 b:2}) {a:3 b:4}) -> (1 4)
在 JavaScript 中等同于:
(function(x){ return function(y){ return [x.a,y.b]; }})({a:1,b:2})({a:3,b:4});
Output: [1,4]
因此,换句话说,lambda 的简短语法(不同于 Clojure 当前的实现)允许嵌套函数。
最佳答案
如果您只想使用不带任何宏的直接 Clojure 代码(即相当于 JavaScript 版本),那么您只需要:
(((fn [x] (fn [y] (list (:a x) (:b y)))) {:a 1 :b 2}) {:a 3 :b 4})
=> (1 4)
如果您为实际的宏标识符选择不同于 #()
的其他形式,您也可以使用宏来执行此操作,例如你可以这样做:
(((my-lambda %a %b) {:a 1 :b 2}) {:a 3 :b 4})
=> (1 4)
(p.s. 我修复了 orginival 问题中的 map 关键字,a:1
将不起作用......)
方法是:
- 创建一个名为
my-lambda
的宏> - 让这个宏检查传递给它的符号,并将它们转换为针对自动生成的符号的关键字查找
- 使用自动生成的符号为函数输出代码,例如:
(fn [sym1] (fn [sym2](list (:a sym1) (:b sym2))))
<
这种方法非常适合嵌套函数。使用 Clojure lambdas 需要知道的重要一点是 (fn [...] ...)
可以嵌套,但是 #(...)
不能(因为它会否则会导致函数参数歧义)。
您不能直接覆盖 #()
语法,因为 Clojure 尚不支持读取器宏。我实际上认为这是一件好事 - 允许任意重新定义语法可能会导致一些人编写非常难以维护的代码而没有明显的好处(节省几个字符的输入但可读性/代码理解能力降低是不是 在我看来是一个好处)。
我想在 Clojure 代码中任何地方看到 #()
我都知道它是一个常规的匿名函数,而不必担心有人重新定义它的可能性奇怪的东西。
关于syntax - 可以使用 Clojure/Lisp 宏来实现此 lambda 语法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12269992/