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

欢迎!请访问关于页面了解有关此功能的更多信息。

0
编译器

我本应预期以下Java交互调用都会避免反射,但只有涉及f1的第一个调用是这样。

`
Clojure 1.6.0
user=> (set! warn-on-reflection true)
true
user=> (defn f1 ^java.util.LinkedList [coll] (java.util.LinkedList. coll))

'user/f1

user=> (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))

'user/f2

user=> (.size (f1 [2 3 4]))
3
user=> (.size (f2 [2 3 4]))
反射警告,NO_SOURCE_PATH:5:1 - 无法解析size字段的引用。
3
`

不确定这与CLJ-1232是否有关系,但这是在测试该问题的变体时发现的。

8 个回答

0

评论者:jafingerhut

这是一个很棒的票据编号,1543。哥白尼最著名的书籍出版的年份:http://en.wikipedia.org/wiki/Nicolaus_Copernicus

0

评论者:wagjo

参数向量的类型提示不应该是仅用于原始类型的提示吗?我想知道非原始类型的提示应该放在函数名上,其他都是非惯用的。

0

评论由:bronsa 提出

这不是 arg 向量提示与函数名提示之间的问题。
这里的本质问题是,返回类型提示不能放在匿名函数上,而只能放在 defn 上,因为 Var 的元数据中会添加 :arglists。

这就是为什么我想将此信息作为 fn 字段附带的,而不是作为 Var 元数据的原因之一

0

评论者:jafingerhut

Jozef,你可能是对的,非原生态类型提示在 arg 向量上不是符合约定的。你能提供我可以阅读的相关资料吗?

0

评论由:tsdh 提出

仅在提及 arg 向量提示的版本在https://clojure.org/java_interop#Java的 Interop-Type Hints 中进行了文档说明。然而,在你只有一个参数(或所有参数都返回相同类型的值)的情况下,在 var 名称上的提示也有效。但这两个版本似乎有不同的语义。看看 CLJ-1232。

0
_评论由:wagjo 提出

类型提示是 Clojure 中的一个非常复杂的部分,但你几乎总能使用 *'place hint on a symbol'* 迭代法。在 arg 向量上进行类型提示只在两种情况下使用
- 原生提示
- 不同 arities 对应不同的返回类

在第一种情况下,编译器在编译 fn*(见 [1])时需要类型提示,不是之后,因此你必须指定它们在 arg 向量上。

第二种情况,这是这里讨论的问题,仅在使用 defn 定义时使用。编译器首先在 var 的元数据中查找标记,如果没有找到,它有一个特殊案例,在 :arglist 元数据中查找返回类。这显然是一个非常特殊的情况 [2],用于处理具有不同返回类的不同 arities 的情况。显然,使用 def 而不是 defn 不会为你创建一个 :arglist 元数据,因此你会看到反射警告。例如


user=> (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))
'user/f2
user=> (.size (f2 [2 3 4]))
反射警告, /tmp/form-init.clj:1:1 - 无法解决引用字段 size。
3
user=> (alter-meta! #'f2 assoc :arglists '([^java.util.LinkedList [coll]]))
{:ns #<Namespace user>, :name f2, :file "/tmp/form-init.clj", :column 1, :line 1, :arglists ([coll])}
user=> (.size (f2 [2 3 4]))
3


顺便提一句,CLJ-1491有一个与此话题稍微相关的讨论。

[1] https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L5134
[2] https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/jvm/clojure/lang/Compiler.java#L3572

0
回答

评论者:wagjo

Andy,我发现了反对我建议的资料 :) 看CLJ-811和(链接:1)。

(链接:1) https://groups.google.com/d/msg/clojure/b005zQCPxOQ/6G0AlWKKKa0J

0
参考: https://clojure.atlassian.net/browse/CLJ-1543 (由jafingerhut报告)
...