Macros 宏的Clojure评估

Macros 宏的Clojure评估,macros,clojure,Macros,Clojure,我在Clojure中构建DSL时遇到问题。这是我从其他一切中分离出来的具体问题 假设我们有一个简单的宏: user> (defmacro m1 [x] `'~x) #'user/m1 它只返回提供的文本 用户>(m1-toUpperCase) 图珀案 若我们为对象调用java方法,一切都会按预期工作 user> (. "a" toUpperCase) "A" 但是如果我们用方法名替换返回方法名的宏调用 user> (. "a" (m1 toUpperCase)) ; E

我在Clojure中构建DSL时遇到问题。这是我从其他一切中分离出来的具体问题

假设我们有一个简单的宏:

user> (defmacro m1 [x] `'~x)
#'user/m1 
它只返回提供的文本 用户>(m1-toUpperCase) 图珀案

若我们为对象调用java方法,一切都会按预期工作

user> (. "a" toUpperCase)
"A"
但是如果我们用方法名替换返回方法名的宏调用

user> (. "a" (m1 toUpperCase))

; Evaluation aborted.
Unable to resolve symbol: toUpperCase in this context
我想使用一些具有流畅接口的java库,如a().b().c()。 这映射到Clojure,如下所示:

(.. obj method1 method2 method3....etc)
我想创建宏来替换此链的某些部分,因此我的代码应该如下所示:

(.. obj method1 macro1)
这应该扩大到

(.. obj method1 method2 method3)

definline也没有帮助。我也试过了

你遇到这个问题的原因是。特殊形式不会以您期望的方式计算其第二个参数(指定方法或字段的符号):它将其视为方法m1的调用,参数toUppercase。因此,您不能动态地为该方法生成符号,将其作为的参数。(点)-即使使用宏指定该参数

解决这一问题的一种方法是将。在宏中:

 (defmacro m1 [x y] `(. ~x (~y)))
 (m1 "a" toUppercase)
 user> "A"
请注意,您需要在~y周围加上括号,以表示您希望调用方法而不是读取字段