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 向量提示与函数名提示之间选择的问题。
问题在于无法对匿名函数使用返回类型提示,而只能对定义使用,因为 var 的元数据上会添加 :arglists。

这就是为什么我想把信息作为一个字段而不是 Var 的元数据放置在 fn 上。

0票数

评论:jafingerhut

Jozef,你可能正确,arg 向量上的非原始类型提示不是习惯用法。你能提供我能阅读的来源吗?

0票数

评论由:tsdh 提出

只有具有 arg 向量提示的版本在 https://clojure.org/java_interop#Java 跨语言-Type 提示中有所记录。但是,在你只有一个可调用性(arity)或所有可调用性返回相同类型的值的情况下,在 var 名称上的提示也适用。但是这两个版本似乎有不同的语义。请参阅 CLJ-1232。

0票数
_评论由:wagjo 提出

类型提示是 Clojure 的一个非常复杂的部分,但您可以几乎总是应用一个 *'place hint on a symbol'* 习惯用法。类型提示在 arg 向量上的使用只有在以下两种情况下进行
- 原始提示
- 不同可调用性具有不同的返回类别

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

第二种情况,这里讨论的问题必须仅在使用 defn 定义时使用。编译器首先在 var 的元数据中查找标签,如果没有找到,它会有一个特殊情况,在其中它会在 :arglist 元数据中查找返回类别。显然,这是处理您具有不同返回类别的情况的一个非常特殊的情况[2]。显然,使用 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 报告)
...