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

欢迎!请参考关于 页面以了解此工作方式的相关更多信息。

+6
Clojure

clojure.walk 中的条件分发较慢,且不能扩展。在 CLJ-1105 之前,它不支持记录。

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

补丁: 0002-CLJ-1239-clojure.walk 协议分发补丁

性能: 我的测试表明,这比原来的 clojure.walk 快 1.5 倍-2 倍。有关基准测试结果,请参阅 https://github.com/stuartsierra/clojure.walk2

风险: 这种方法存在破坏依赖于旧 clojure.walk 类型特定行为的用户代码的风险。在运行完整的 Clojure 测试套件时,我发现并修复了一些在 clojure.walk 的单元测试中没有出现的破坏性情况。例如,请参阅(链接:https://github.com/stuartsierra/clojure.walk2/commit/730eb756dcc424aa535d0872bd626079955c3892 text: clojure.walk2 中的提交 730eb75)。

10 回答

0
index.php/2376/faster-more-flexible-dispatch-for-clojure-walk?show=2538#a2538" class="qa-a-item-what" itemprop="url">回答

评论者:jafingerhut

补丁0001-CLJ-1239-protocol-dispatch-for-clojure.walk.patch已不再干净地应用于最新的Clojure master,因为针对CLJ-1105的补丁已于2013年11月22日提交。从描述来看,意图似乎是这个补丁之一,而不是两个,因此我不确定这个补丁应该如何处理,甚至整个工单。

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的实现当前无法保留元数据。

如果这条新的实现被回头审视,在可能的情况下保留元素的元数据将会是件好事。

...