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

arg vector的类型提示不应该是仅用于原始类型提示的吗?据我所知,非原始类型提示应该放在函数名上,其他都是非惯用的。

0

评论者:bronsa

这并不是类型向量提示与函数名提示的问题。
这里的问题是,无法将返回类型提示放在匿名函数上,只能放在定义(defn)上,因为类型向量(:arglists)将由定义(defn)添加到 Var 的元数据中。

这就是我希望将该信息作为函数的字段而不是作为 Var 的元数据的原因之一。

0

评论者:jafingerhut

Jozef,你可能会认为参数向量上的非原始类型提示不符合直觉。你能提供一些我可以阅读的参考资料吗?

0

评论者:tsdh

只有包含参数向量提示的版本在https://clojure.org/java_interop#Java的 Interop-Type Hints 中进行记录。然而,如果你只有一个参数数量(或所有参数数量的返回结果类型相同),在 var 名称上添加提示也是有效的。但是这两个版本似乎具有不同的语义。请参阅 CLJ-1232。

0
_评论者:wagjo_

类型提示是 Clojure 中的一个非常复杂的部分,但你几乎总是可以用“在符号上放置提示”的惯用法来实现它。只有在两种情况下才能在参数向量上进行类型提示:
- 原始提示
- 对于不同参数数量具有不同的返回类型

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

第二种情况,就是我们这里讨论的问题,仅在定义使用 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 汇报)
...