Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 有没有办法内联传递给宏的函数?_Clojure_Macros - Fatal编程技术网

Clojure 有没有办法内联传递给宏的函数?

Clojure 有没有办法内联传递给宏的函数?,clojure,macros,Clojure,Macros,例如,我可以编写如下宏: (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

例如,我可以编写如下宏:

(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)

我是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)

关于你实际提出的问题,我会说:不要这样做。内联是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)))))

你想干什么?可能有更好的方法来实现您的最终目标。@exupero我正在尝试加快宏生成的代码的速度。确切的代码是:,我正试图通过将重复部分提取到分支中来减少
cond
分支中的重复。@exupero
doseq
aset lights I
之间的所有内容都是完全相同的,避免重复代码会很好。因此,您想到的是函数
(fn[I]是的)
(fn[i]false)
(fn[i](不是(aget lights i)))
,对吗?@Rulle是的,就像那样。我非常欣赏干净的代码,而且你的版本确实比基于宏的、带有可怕内联的替代版本干净得多。然而,它也慢得多——因为我们一次又一次地调用函数。我知道微基准是非常邪恶的,但在这种情况下,结果似乎是明确的-基于宏的版本在8.6秒工作,你的版本花了282秒。显然,JVM有其局限性。下面是我用来进行基准测试的代码:s/m3/apply one/@cfrick-谢谢!