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)

因为这个代理没有实现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对象的是一个(只读的)Map视图。empty是一个修改操作,我们不支持类似记录这一类的操作。

我并不反对问题陈述 —— 我认为这是一个合理的用例。但我认为修复应该在walk而不是bean中。

0 点赞

评论者:sunng

更新描述并添加复现步骤

0 点赞

评论者:sunng

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

0 点赞

评论者:alexmiller

这些都是不可变集合,所以我在这里不讨论实际的修改,而是讨论从一种不可变结构到另一种结构的改变。有几个现有案例,我们有不支持empty的不可变集合,因为这在概念上没有意义,比如record实例和map条目。

我想说的是,我认为这属于这种情况之一,不管特定的接口和实现路径是否允许调用该方法。从概念上讲,bean创建的实例是Java对象的只读视图。为对象视图“清空”没有任何意义 —— 对象总是有字段(这与固定字段的record和有键/值的map条目是相同的论点)。我相信在ClojureScript中,实际上有一个协议来标记集合是否可以被清空,这可能在这里也很有意义。

0 点赞
0 点赞
by

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

...