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}


请注意,{{[: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

评论由:bronsa 发布

Alex,就clojure-1.6.0版本在CLJ-1105之后表现出的行为而言,与Chouser在本补丁中描述的一致

0

评论由:glts 发布

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

如果将来要重新审视此新实现,最好也尽可能保留元素上的元数据。

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