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

欢迎!请查看关于页面以了解更多关于如何使用的资料。

+6
Clojure

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

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

补丁: 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主分支,因为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}


注意map中的{{[:a 1]}}条目已被移除,但是record中没有。

以下是一个不会遇到那个问题的实现,尽管它对类名进行了恐怖的修改: 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

评论人:bronsa

Alex,就 clojure-1.6.0 在 CLJ-1105 之后显示的行为与 Chouser 在此补丁中描述的行为相同

0

评论人:glts

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

如果将来有机会重新审阅这个新实现,也请在可能的情况下保持这些元素的元数据。

0
参考:https://clojure.atlassian.net/browse/CLJ-1239 (由 stuart.sierra 报告)
...