首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >宏的闭包计算参数

宏的闭包计算参数
EN

Stack Overflow用户
提问于 2015-09-28 22:47:31
回答 2查看 710关注 0票数 2

我正在尝试编写一个为core.match宏生成模式的宏。

代码语言:javascript
复制
(defmacro match2
  [state i predecessor]
  `(match ~[state]
          [(~(vec (concat (repeat i '_)
                           predecessor
                           '(& r)))
            :seq)] ~i
          :else false))

如果我直接将它与硬编码的前驱者一起使用,这是很好的。

代码语言:javascript
复制
(match2 ["B"] 0 ["B"]) ; 0

到目前为止,一切都很好,但是如果我试图使用函数调用传递前任:

代码语言:javascript
复制
(match2 ["B"] 0 ((fn [] ["B"]))) ; AssertionError Invalid list syntax [] in (fn [] ["B"])

问题是,因为match2是一个宏,clojure不会计算函数调用,而只会传递它的形式。然后,未计算的表单转到core.match (也是未计算的,因为core.match本身是一个宏),core.match抛出异常,因为表单是不正确的模式。

如何在宏观论证上强制进行评估?或者其他的解决办法?

我被暗示这通常是用第二个宏完成的,但是我的尝试没有取得好的结果。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-29 15:59:02

core.match是一个编译器。它将一些表单转换为可执行表达式。它可以处理的表单必须遵守语法,从而引发断言。作为一个宏,它编译在..。编译时间。无论您如何努力,都不能让它编译运行时表达式的结果。

即使您设法在编译时对(fn [] ["B"])进行评估,以便将该值提供给match,但我认为这不是您的目标。您想要做的是与程序逻辑计算的表达式进行匹配。在那里,抱歉地说core.match是不可能的,诺伦证实了这一点。

尽管如此,matchure还是可以这样做的:在运行时创建匹配函数/表达式,参见fn-match。这是未维护的AFAIK,但只是工作。一段时间前,我对它进行了修补,以便使用CLJ1.6,这里

票数 -1
EN

Stack Overflow用户

发布于 2015-09-28 23:09:41

我有两种选择。在宏中使用eval。

或者,您可以让宏不调用match宏。让它调用另一个函数,该函数调用匹配宏。这将迫使评估在途中匹配。

下面是一篇关于这类问题的好文章:

http://amalloy.hubpages.com/hub/Clojure-macro-writing-macros

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32832982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档