Macros 在Clojure宏中强制展开表达式
我试图在Macros 在Clojure宏中强制展开表达式,macros,clojure,Macros,Clojure,我试图在defprotocol中使用Stuart Sierra的宏,Clojure编译器抱怨我正在重新定义do模板——这不是我想要的: (defprotocol AProtocol (a-method [_]) (do-template [name] `(~(symbol (str name "-method")) [this that]) foo bar baz)) 这应扩大到: (defprotocol AProtocol (a-method [
defprotocol
中使用Stuart Sierra的宏,Clojure编译器抱怨我正在重新定义do模板
——这不是我想要的:
(defprotocol AProtocol
(a-method [_])
(do-template [name]
`(~(symbol (str name "-method")) [this that])
foo
bar
baz))
这应扩大到:
(defprotocol AProtocol
(a-method [_])
(foo-method [this that])
(bar-method [this that])
(baz-method [this that]))
问题(我相信)是do模板
s表达式正在被传递到defprotocol
未展开。有没有办法让它在通过之前进行评估
顺便说一句,do模板
实际上应该扩展到
(do
(foo-method [this that])
(bar-method [this that])
(baz-method [this that]))
但是我已经尝试过了(用一个手动扩展的版本),并且defprotocol
可以使用嵌套的do
如何查看do模板的实际扩展?我尝试了(宏扩展)(do模板…)
和(宏扩展-1)(do模板…)
,得到了:
(do(clojure.core/seq)
(clojure.core/concat)
(clojure.core/list(符号(str foo
“-method”))(clojure.core/list
(clojure.core/apply)
clojure.core/vector(clojure.core/seq
(clojure.core/concat)
(clojure.core/list(引用用户/this))
(clojure.core/list(引用)
用户/该(()(()()(()))(clojure.core/seq
(clojure.core/concat)
(clojure.core/list(符号(str-bar
“-method”))(clojure.core/list
(clojure.core/apply)
clojure.core/vector(clojure.core/seq
(clojure.core/concat)
(clojure.core/list(引用用户/this))
(clojure.core/list(引用)
用户/该(()(()()(()))(clojure.core/seq
(clojure.core/concat)
(clojure.core/list)(符号(str baz
“-method”))(clojure.core/list
(clojure.core/apply)
clojure.core/vector(clojure.core/seq
(clojure.core/concat)
(clojure.core/list(引用用户/this))
(clojure.core/list(引用)
用户/该(()()())())()))
不太容易阅读:-)
另外,我可能希望这个
和那个
是回指并扩展到它们自己:~'this
(1)defprotocol不适合do形式。它不会引发错误,但也不起作用
(2) 你不能用这种方式做你想做的事。defprotocol是被调用的宏,因此它对如何扩展子窗体具有绝对权限
(3) 第(2)项提出了一个解决方案,实际上至少与您最近提出的一个问题相同:定义一个新的宏,比如说带有方法的,,该宏包含一个方法名列表,后跟任何其他defprotocol参数,并扩展为一个defprotocol,其中已经完成了适当的替换和拼接,这样,defprotocol就可以和平地扩展,而无需了解您的do模板技巧。谢谢。我将编写buildprotocol
和build-reify
宏来创建适当的结构,每个结构都有一个类似(buildprotocolname simple&complex)
的签名,其中simple
是“简单”声明的向量((a-method[this])
)而complex
是零个或多个表单,它们被插入~@
。