请在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

评论者:jafingerhut

这不是一个关于描述中的行为是否为错误的问题,而是一个关于人们在宏中设置宏展开时副作用的频率的好奇心。我认为Clojure自身中有以下内容,但可能有其他更多的内容

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

评论者:bronsa

Andy,我认为没有太多在宏展开时产生副作用的宏,并且我在考虑在Compiler.java中实现循环局部变量无效化时没有在实际代码中发现这个错误。

因为确实有很多副作用少的宏,这不太可能在实际代码中导致问题,所以我将其优先级改为次要。

0

评论者:arcata

关于现实意义:Cloverage,Clojure代码覆盖率工具,严重依赖副作用宏,这个bug导致我经常得到损坏的覆盖率结果。我已在(链接:https://github.com/cloverage/cloverage/issues/240 文本:Cloverage的问题跟踪器)上发布了关于此的帖子。

0

评论者:admin

什么是“不匹配的递归”?能否描述得更加精确?在类型、箭头长度或目标方面是否存在不匹配?

0
评论者:bronsa

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



FWIW,“类型不匹配”是Compiler.java用来指代这种情况的术语。
0
参考:[a href="https://clojure.atlassian.net/browse/CLJ-1407" rel="nofollow" target="_blank">https://clojure.atlassian.net/browse/CLJ-1407(由bronsa报告)
...