例如,我可以编写这样的宏:
(defmacro apply-one [f]
`(~f 1))
(println (apply-one (fn [x] (+ 42 x))))
; => 43
但是宏扩展会导致额外的函数调用:
(macroexpand '(apply-one (fn [x] (+ 42 x))))
; => ((fn [x] (+ 42 x)) 1)
有没有一种方法可以“内联”传递的函数,以便:
(macroexpand '(apply-one (fn [x] (+ 42 x))))
; => (+ 42 1)
答案 0 :(得分:3)
关于您实际提出的问题,我会说:不要这样做。内联是JVM做得很好的事情之一,并且您不应该使您的代码更复杂,更易读,以确保某些内容可以内联。
您原始的问题陈述(发表在评论中)有一个更干净的解决方案:不要重复任何内容!不用编写带有三个几乎相同的子句的cond
表达式,而是使用cond
为唯一变化的部分设置变量,然后使用您设置的变量无条件地处理其余部分
(let [compute (case command
"turn on" (constantly true)
"turn off" (constantly false)
"toggle" not)]
(doseq [x (range x1 (inc x2))
y (range y1 (inc y2))
:let [i (+ (* y W) x)]]
(aset lights i (compute (aget lights i)))))
答案 1 :(得分:0)
我是Clojure的新手,所以以下解决方案对我来说既恐怖又美丽。但这仍然是一个解决方案。
(defmacro apply-one [f]
(eval `(~f 1)))
(println (apply-one (fn [x] `(+ ~x 42))))
; => 43
(pprint (macroexpand-1 '(apply-one (fn [x] `(+ ~x 42)))))
; => (clojure.core/+ 1 42)