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 master 上,因为 CLJ-1105 修复补丁已于 2013 年 11 月 22 日提交。从描述中看,意图可能是这两个补丁中的一个,而不是两者都适用,因此我不确定这个补丁,甚至这个工单应该如何处理。

0
by

评论者:alexmiller

这个补丁和工单仍然是未来版本候选。

0
by

评论者:stuart.sierra

添加了新补丁,该补丁在 CLJ-1105 之后适用于最新 master。

0
by
评论者:[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
by

评论者:alexmiller

@Chouser,你是否可以针对此问题提交一个新的工单?从关闭的工单上的评论管理工作很困难。

0
by

评论者: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报告)
...