请分享您的想法,参加 2024 Clojure 状态调查!

欢迎!请参阅 关于 页面以获取更多有关此信息。

0
集合
已关闭

https://github.com/clojure/clojure/blob/010864f/src/clj/clojure/core.clj#L6553-L6562

因为 PHMs 实现了 clojure.lang.IKVReduce IPersistentMap,它们会通过支持 reduce-kv 的协议(clojure.core.protocols/IKVReduce)进行非确定性的分派。

解决这个问题的一个潜在方法是在 reduce-kv 中添加对 clojure.lang.IKVReduce 的实例检查(这与 reduce 检查 IReduceInit 的方式类似)。

另一种方法是将协议扩展到 PersistentHashMap 和 PersistentArrayMap(同时保留现有的扩展)。

已关闭,备注:已在 1.11.0-alpha2 中修复

3 个答案

0

由 bronsa 发布的评论

CLJ-1807 为这类问题提供了一个通用解决方案

0
由 gshayban 发布的评论

重示例代码


(def C (atom 0))

;; 重新扩展以进行仪器化
(extend-protocol clojure.core.protocols/IKVReduce
 ;; 慢速路径默认
 clojure.lang.IPersistentMap
 (kv-reduce
   [amap f init]
   (swap! C inc)
   ((reduce (fn [ret [k v]] (f ret k v)) init amap)))

(reduce-kv (fn [_ _ _]) nil (array-map 1 2 3 4))
(println "slowpaths" @C)
(reduce-kv (fn [_ _ _]) nil (hash-map 1 2 3 4))
(println "slowpaths" @C)




重生产输出

➜  dev /usr/lib/jvm/java-8-openjdk/bin/java -cp $(clojure -Spath) clojure.main kvfastpath.clj
slowpaths 1
slowpaths 2
➜  dev /usr/lib/jvm/java-11-openjdk/bin/java -cp $(clojure -Spath) clojure.main kvfastpath.clj
slowpaths 0
slowpaths 0
0
by
参考: https://clojure.atlassian.net/browse/CLJ-1879 (由gshayban报告)
...