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 投票

评论人: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保持更专一的焦点(我的补丁可能不可接受,或者可能太大且做太多)则不是重复的。我多少自己承担了解决这两个问题的重任,因为我是从Nicola在这里的评论开始了解CLJ-701的,并且相同的编译器机制可以为这两个实现

我认为状态是等待CLJ-701的状态。

0 投票
by
...