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,以返回同一类别的空集合。持久数组映射的实现只是返回一个缓存的空实例。它们都没有改变原始集合。因此,我认为在此处返回空映射是合理的。

0

评论者:alexmiller

这些都是不可变集合,所以我谈论的不是实际的修改,而是从一种不可变结构到另一种不可变结构的转换。有几种现有的用例,我们有不支持空的不可变集合,因为在概念上讲不通,例如记录实例和映射条目。

我的意思是,我相信这可能是那些情况之一,无论特定的接口和实现路径是否允许调用该方法。在概念上,bean 创建了一个实例,该实例是 Java 对象的只读视图。将对象视图“清空”是不合理的 - 对象始终有字段(这与记录相同,记录具有固定字段,与映射条目相同,它们具有键/值)。我认为在 ClojureScript 中实际上有一个协议来标记集合是否可以清空,也许这也适用于此处。

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

我认为为APersistentMap添加一个特殊情况,直接在walk内部使用(into {} ...,将修复此问题。

...