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 由于 CLJ-1105 的补丁于 2013 年 11 月 22 日提交,现在不再干净地应用于最新的 Clojure master。根据描述,意图是或者这个补丁或者那个补丁,而不是两者,所以我不是很清楚这个补丁或甚至这个条目的处理方式。

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](https://clojure.atlassian.net/browse/CLJ-1239)(由 stuart.sierra 报告)
...