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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
Macros 在Clojure宏中强制展开表达式_Macros_Clojure - Fatal编程技术网

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
是零个或多个表单,它们被插入
~@