【发布时间】:2015-03-03 11:04:51
【问题描述】:
想象一下,我的意图是修改传递给宏的 s 表达式的语法树,方法是修改语法树,然后评估修改后的参数。我可以执行以下操作:
(defmacro runargs [args]
(eval (cons (first args) " buckeroo")))
(runargs (println "hi there"))
现在这不感觉惯用,因为我在我的代码中间敲了一个大的eval。
现在我稍微修改一下,得出以下结论:
(defmacro runargs [args]
`(~@(cons (first args) " buckeroo")))
(runargs (println "hi there"))
这解决了eval 的问题。但我仍然觉得这不是很地道。
我的问题是:在 Clojure 宏中评估修改参数的惯用方法是什么?
【问题讨论】:
-
你能提供你想要的输出,包括 AST-wise 和打印的输出吗? (因为给定的代码不会打印
buckeroo,而是b u c k e r o o,我不确定这是否是有意的。) -
我很抱歉。让我们假设这是有意的。
-
使用宏的“诀窍”是清楚地了解宏展开后代码的外观。由此,您可以识别您正在尝试执行的操作的模板。一旦你有了它,那么宏的定义就相当简单了。在大多数情况下,您不希望宏评估参数 - 它更多的是在编译时将参数重新排列为新形式,然后在运行时进行评估。考虑如果参数是(inc x ) 而不是 println 和字符串 - 编译时 x 是什么? inc 应该何时发生?
标签: clojure macros arguments eval