2024年Clojure调查问卷!中分享您的想法。

欢迎!请参阅关于页面,了解有关此功能的更多详细信息。

+1
Java 兼容

目前,如果您在从(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)

因为代理未实现空接口,而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

这些都是不可变集合,我所说的不是真正的修改,而是从一种不可变结构到另一种结构的变更有瑕疵。有几个现有的案例中我们有不支持的空集合的不可变集合,因为它们在概念上不合理,比如记录实例和映射条目。

我要说的是,我认为这是那种情况之一,无论特定的接口和实现在概念上是否允许调用该方法。在概念上,bean 创建了一个 Java 对象的只读视图的实例。在没有字段的对象视图中进行 "empty" 没有意义——对象总有字段(这与具有固定字段的记录和具有键/值的映射条目相同的论点)。我相信 ClojureScript 中实际上有一个协议来标记集合是否可以清空,也许这也适用于此处。

0
参考:[https://clojure.atlassian.net/browse/CLJ-2399](https://clojure.atlassian.net/browse/CLJ-2399) (sunng 提出)
0
by

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

...