2024 Clojure 状态调查!中分享您的想法。

欢迎!有关该平台的工作方式,请参阅关于页面以获取更多信息。

+1
编译器

原始函数和 recur 变量无法干净地通过 (try),它们被包裹为 Object。这会导致使用原始类型的方法或循环出现反射警告。

`
user=> (set! warn-on-reflection true)
true

user=> (fn [] (loop [t 0] (recur t)))

<user$eval676$fn677 user$eval676$fn677@3d80023a>

user=> (fn [] (loop [t 0] (recur (try t))))
NO_SOURCE_FILE:1 recur 参数对于原始局部变量: t 与原始类型不匹配,有: Object,需要: long
自动装箱循环参数: t

<user$eval680$fn681 user$eval680$fn681@5419323a>

user=> (fn [^long x] (recur (try x)))
NO_SOURCE_FILE:1 recur 参数对于原始局部变量: x 与原始类型不匹配,有: Object,需要: long

编译器异常 java.lang.IllegalArgumentException: recur 参数对于原始局部变量: x 与原始类型不匹配,有: Object,需要: long,编译:(NO_SOURCE_PATH:1:1)
`

7 回答

0

评论者:davidj

不评论最理想的行为,以下代码不会引发反射警告

`
user=> (set! warn-on-reflection true)
true
user=> (fn [] (loop [t 0] (recur (long (try t)))))

<user$eval673$fn674 user$eval673$fn674@4e56c411>

`

0

评论者:bronsa

相关工单http://dev.clojure.org/jira/browse/CLJ-701

0
by

由 hiredman 发布的评论

编译器中的 try/catch 只实现了 Expr,而不是 MaybePrimitiveExpr,查看通过在 TryExpr 中扩展 MaybePrimitiveExpr 来实现它似乎很简单,但事实证明 recur 会检查它在语句上下文中的参数,这使得 (try ...) 实质上将其自身包裹在一个函数中,如 ((fn (link: ) (try ...))),此时它是一个 invokeexpr,这会使添加 maybeprimitiveexpr 变得更加困难,并且它归结为与 CLJ-701 相同的情况

0
by

由 hiredman 发布的评论

http://dev.clojure.org/jira/browse/CLJ-701 有一个补丁,我认为它解决了这个问题

0
by

由 alexmiller 发布的评论

我应该把它复制到 CLJ-701 吗?

0
by

由 hiredman 发布的评论

如果您想将 try 的修复作为 CLJ-701 的一部分,那么它是重复的,如果您不确定或更希望 701 保持更集中的关注(我的补丁可能不太可接受,或者可能太大,做得太多)那么就不是重复的。我在柳-701 的补丁中解决了这两个问题,因为我通过尼古拉的评论来到柳-701,同样的编译器机制可以用于两者。

我认为状态有待 CLJ-701 的状态。

0
by
...