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.5x-2x。有关基准测试,请参阅 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报告)
...