2024 Clojure 状况调查中分享您的看法!

欢迎!请查看关于页面以了解更多关于如何工作的信息。

0
编译器

由于匹配不匹配的递归(循环体中的局部变量与循环参数具有不同的类型)导致循环体被重新分析,循环体中的宏展开可能发生多次,导致宏展开期间发生的任何副作用可能被评估多次。

`
Clojure 1.7.0-master-SNAPSHOT
user=> (defmacro x [] (println "foo"))

'user/x

user=> (fn [] (loop [y 1] (x) (recur (Integer. 1))))
foo
foo

<user$eval6$fn7 user$eval6$fn7@71687585>

`

6 答案

0
by

由:jafingerhut 评论

这不是一个关于描述中的行为是否是错误的问题,而是一个关于人们在宏展开时间具有副作用宏的频率的好奇。我认为Clojure本身中以下是这样做的,但可能有其他情况

  • gen-class,以及ns因为它使用gen-class
  • gen-interface,以及definterface因为它使用gen-interface
  • clojure.core/compile-if(私有)调用其expr参数的eval,但现在使用时不导致宏展开时间副作用
  • doc似乎有一个在宏展开时间打印的情况
  • 我不确定defprotocol或deftype是否有宏展开时间副作用,或者它们是否仅限于运行时
0
by

由:bronsa 评论

Andy,我认为在宏展开时间具有副作用的宏并不多,我还没有在真实代码中发现这个错误,但在思考在Compiler.java中实现循环局部变量无效化时。

由于副作用宏确实非常少,因此这不太可能在实际代码中引起问题,所以我将其优先级改为次要。

0

评论文本作者:arcatan

关于实际影响的评论:Cloverage(Clojure代码覆盖率工具)严重依赖于副作用宏,而这个错误导致我经常得到损坏的覆盖率结果。关于这个问题,我已在(链接:https://github.com/cloverage/cloverage/issues/240 文本:Cloverage的问题跟踪器)中发表。(亦称 Cloverage 的问题跟踪器)。

0

评论文本作者:admin

什么是“不匹配的递归”?能否使其更加精确?类型、arity 还是 target 的不匹配?

0
_评论文本作者:bronsa_

类型不匹配,工单中的示例显示在本地从 long 切换到 Integer



FWIW,“类型不匹配” 是 Compiler.java 中用来表示这种情况的术语
0
参考:https://clojure.atlassian.net/browse/CLJ-1407(由 bronsa 报告)
...