syntax - 可以使用 Clojure/Lisp 宏来实现此 lambda 语法吗?

标签 syntax clojure macros lambda nested-function

((#(%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/

相关文章:

java - 没有大括号的嵌套 if-else 行为

macros - 在 clojure 中恢复到宏中的全局范围?

Python - 元组分配是否有 "don' t care"符号?

c - 如何准确理解 malloc() 和 calloc() 两个函数的语法

regex - clojure 相当于 ruby​​ 的 gsub

algorithm - 如何以允许在任何索引处快速插入的方式表示一行音符?

algorithm - 在 clojure[script] 中,如何返回 2 个排序向量之间最近的元素

ios - 为什么我的 DEBUG 预处理器宏没有被识别 objective-c

用于访问 COM 对象属性的 C++ 包装函数(宏)

php - 在 MySQL 中使用 IN/LIKE、TRIM 或 CONTAINS 提取数据库中的变量数据