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对象的映射。empty是一个会修改内容(mutating)的操作,而我们不支持对具有类似目的的记录等对象执行此操作。

我没有反对问题陈述 - 我认为这是一个合理的使用场景。但我认为修复应该发生在walk而不是bean中。

0

评论者:sunng

更新说明并添加重复步骤(reproduce)

0

评论者:sunng

谢谢,Alex。我再次查看了clojure.core/empty的文档,它确实提及委托到IPersistentCollection的.empty,以返回同类别的一个空集合。PersistentArrayMap的实现仅返回缓存的空实例。这两个都没有修改原始集合。所以我认为在这里返回一个空映射是合理的。

0

评论者:alexmiller

这些都是不可变集合,所以这里不是关于真正的修改,而是关于从一种不可变结构到另一种不可变结构的变化。我们已经有一些案例,其中不可变集合不支持empty,因为这从概念上讲是不合理的,例如具有固定字段的record实例和map条目。

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

0
0

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

...