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

欢迎!请参阅关于页面以了解有关如何工作的更多信息。

+6
Clojure

clojure.walk的条件调度速度慢且不支持扩展。在CLJ-1105之前,它不支持record。

方法:使用协议重新实现clojure.walk。公共API未改变。如果需要,用户可以扩展{{walk}}协议到其他类型(例如Java集合)。与CLJ-1105一样,此版本的clojure.walk支持record。

补丁:0002-CLJ-1239-protocol-dispatch-for-clojure.walk.patch

性能:我的测试表明,这比原始的clojure.walk快1.5倍到2倍。请参阅https://github.com/stuartsierra/clojure.walk2以获取基准测试。

风险:这种方法有可能破坏依赖旧clojure.walk特定类型行为的用户代码。当运行完整的Clojure测试套件时,我发现(并修复)了一些在clojure.walk单元测试中没有显示的破坏性。例如,请参阅(链接:https://github.com/stuartsierra/clojure.walk2/commit/730eb756dcc424aa535d0872bd626079955c3892 文本:clojure.walk2中的提交730eb75)。

10个回答

0

由vmarcinko发表的评论

看起来,当前版本在遍历树和替换形式时不会保留数据结构中包含的原始元数据。

0

由jafingerhut发表的评论

补丁0001-CLJ-1239-protocol-dispatch-for-clojure.walk.patch已不再适用于最新的Clojure master,因为CLJ-1105的补丁已于2013年11月22日提交。从描述来看,补丁的意图似乎是这两个中的一个,而不是两个都包含,因此我不确定应该如何处理这个补丁,甚至是这个工单。

0

评论者:alexmiller

此补丁和工单仍然是未来发布的候选人。

0

评论者:stuart.sierra

在CLJ-1105之后,添加了适用于最新主分支的新补丁。

0
_ 评论者:[email protected]_

与常规映射相比,此补丁的行为可能与预期不同


(clojure.walk/prewalk-replace {[:a 1] nil} {:a 1, :b 2})
;=> {:b 2}

(defrecord Foo [a b])
(clojure.walk/prewalk-replace {[:a 1] nil} (map->Foo {:a 1, :b 2}))
;=> #user.Foo{:a 1, :b 2}


请注意,从映射中删除了{{[:a 1]}}条目,但并未从记录中删除。

以下是一个不遭受此问题困扰的实现,尽管它执行了令人生畏的类名篡改: https://github.com/LonoCloud/synthread/blob/a315f861e04fd33ba5398adf6b5e75579d18ce4c/src/lonocloud/synthread/impl.clj#L66

也许我们可以扩展defrecord抽象,以更好地支持synthread代码笨拙执行的事情,然后{{walk}}可以利用这一点。
0

评论者:alexmiller

@Chouser,你可以就此事提交新的工单吗?从已关闭工单的评论中管理某些工作的难度很大。

0

评论者:alexmiller

@Chouser - 无需担心!我琢这个是进入1.6的更改,继续吧。 :)

0
by

评论者:bronsa

亚历克斯,就此事而言,clojure-1.6.0 在 CLJ-1105 之后表现出和 Chouser 描述的该补丁相同的特性。

0
by

评论者:glts

当前 clojure.walk 的实现不保留元数据。

如果今后再次审视此新实现,能够尽可能地在元素上保留元数据将会很好。

0
by
参考文献:[https://clojure.atlassian.net/browse/CLJ-1239](https://clojure.atlassian.net/browse/CLJ-1239)(stuart.sierra 报告)
...