2024年Clojure状态调查 中分享您的看法!

欢迎!请参阅关于 页面以获取更多关于这个工作原理的信息。

0 投票
编译器

我原本预期下面的两个Java互操作调用都可以避免反射,但只有涉及f1的第一个可以。

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

'用户/f1

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

'用户/f2

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

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

8 个答案

0 投票

评论者:jafingerhut

这是多么美的一个票据号,1543。哥白尼最著名书籍出版的那一年:http://en.wikipedia.org/wiki/Nicolaus_Copernicus

0 投票

评论者:wagjo

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

0 投票

评论者:bronsa

这不是参数向量提示与函数名提示之间的问题。
问题在于无法在匿名函数上放置返回类型提示,而只能在定义上放置,因为 :arglists 将由定义添加到 Var 的元数据上。

这就是为什么我希望这个信息作为一个字段而不是元数据放在 fn 上

0 投票

评论者:jafingerhut

Jozef,你可能认为参数向量上的非原始类型提示是非惯例的。你能提供我可以阅读的资源吗?

0 投票

评论者:tsdh

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

0 投票
_评论者:wagjo_

类型提示是 Clojure 中的一个复杂部分,但你几乎总是可以在符号上应用一个 *'place hint* 代码。
- 原始提示
- 不同参数数量的返回类型不同

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

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


用户=> (def f2 (fn ^java.util.LinkedList [coll] (java.util.LinkedList. coll)))
#'user/f2
用户=> (.size (f2 [2 3 4]))
反射警告,/tmp/form-init.clj:1:1 - 无法解析字段大小。
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])}
用户=> (.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 提出)
...