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

欢迎!请查阅关于页面以获取更多关于如何使用本站的详细信息。

+1
Java Interop

目前,如果在对由(bean)生成的代理运行 clojure.walk 函数时,将抛出异常

(clojure.walk/prewalk identity (bean (java.util.Date.)))

 (link: java) ERROR in (test-walk-bean) (:-1)
 (link: java) expected: (clojure.walk/prewalk identity b)
 (link: java)   actual: java.lang.UnsupportedOperationException: empty
 (link: java)  at clojure.core.proxy$clojure.lang.APersistentMap$ff19274a.empty (:-1)
 (link: java)     clojure.core$empty.invokeStatic (core.clj:5202)
 (link: java)     clojure.walk$walk.invokeStatic (walk.clj:49)
 (link: java)     clojure.walk$prewalk.invokeStatic (walk.clj:64)
 (link: java)     clojure.walk$prewalk.invoke (walk.clj:60)
 (link: java)     clojure.lang.AFn.applyToHelper (AFn.java:156)
 (link: java)     clojure.lang.AFn.applyTo (AFn.java:144)
 (link: java)     clojure.core$apply.invokeStatic (core.clj:657)

因为代理没有实现 empty,这是 clojure.walk 所要求的。此补丁添加了一个重现问题的测试和修复。

9 个答案

0

评论由:alexmiller 发表

能否在描述中添加重现步骤?

并且如果你还没有签署贡献者协议,请签署,否则我们无法考虑这个补丁。 https://clojure.org/community/contributing

谢谢!

0

评论由:sunng 发表

看起来描述无法编辑。

我已经在补丁中包含了一个用于重现此问题的测试用例。

(clojure.walk/postwalk identity (bean (java.util.Date.)))

我已经签署了协议,作为(Ning Sun,[email protected],github:sunng87)。

0

评论由:alexmiller 发表

谢谢,我已赋予您编辑权限。

0

评论由:alexmiller 发表

仔细观察了一下,我认为您提出的解决方案并不合理。Bean提供了一个(只读)的Java对象映射视图。empty是一个会改变(集合)的操作,我们不支持诸如记录这样的具有类似功能的对象使用这个操作。

我没有反对问题陈述 - 我认为这是一个合理的用例。但我觉得修复应该是在walk中,而不是在bean中。

0

评论由:sunng 发表

更新描述并添加复现步骤

0

评论由:sunng 发表

谢谢,Alex。我再次检查了clojure.core/empty文档,它确实这样说了,它委托给了IPersistentCollection的.empty,是为了返回同一种类的一个空集合。PersistentArrayMap的实现只是返回了一个缓存的空实例。它们都没有改变原始集合。所以我认为在这里返回一个空映射是合理的。

0

评论由:alexmiller 发表

这些都是不可变集合,我谈论的不是实际的变化,而是从一种不可变结构到另一种结构的改变。我们有几个现存的案例,其中不可变集合不支持empty,因为这个操作从概念上讲没有意义,比如记录实例和映射条目。

我的观点是,我认为这是一个这样的案例,不管特定的接口和实现路径是否允许该方法被调用。从概念上讲,bean创建了一个实例,它是Java对象的只读视图。不要“清空”对象视图是没有意义的 - 对象总是有字段(这与记录相同,记录有固定字段,映射条目有键/值)。我相信在ClojureScript中实际上有一个协议用来标记一个集合是否可以被清空,也许这在这里也是合理的。

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

我认为为APersistentMap添加一个特殊案例,在walk中使用(into {} ...,可以解决这个问题。

...