【发布时间】:2014-10-17 09:32:24
【问题描述】:
这是一个演示问题的简短 sn-p:
(defmulti test-dummy type)
(defmacro silly [t]
`(defmethod test-dummy ~(resolve t) [some-arg] "FOO!"))
(silly String)
评估此结果会导致“无法使用限定名称作为参数:user/some-arg”,但运行宏扩展会得到非常好的结果:
(defmethod test-dummy java.lang.String [some-arg] "FOO!")
在参数名称之前键入 ~' 以使其评估为符号有效,但这是怎么回事?
【问题讨论】:
-
也许你可以使用 autogensym 来避免这种情况。将宏定义中的
some-arg更改为some-arg#。 -
好的,但是为什么会这样呢?为什么我会从 macroexpand 中得到正确的表达式?
-
遗憾的是,
macroexpand函数与编译器并非 100% 兼容。也就是说,我没有看到与您相同的宏扩展:(. user/test-dummy clojure.core/addMethod java.lang.String (clojure.core/fn [user/some-arg] "FOO!"))- 此命名空间符合some-arg,这是 ` 的预期和记录行为 -
@noisesmith:你是对的。用于 emacs 的 CIDER REPL 似乎存在问题。文档指出 C-c C-m 调用 macroexpand-1,但手动调用它会返回不同的结果,与您得到的结果相同。我想这两个谜团都解决了。
-
我不再对苹果酒中的任何奇怪现象感到惊讶。