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

欢迎!请参阅关于页面以了解有关此功能的更多信息。

0
集合
已关闭

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

因为PH Ms实现clojure.lang.IKVReduce并且IPersistentMap,它们通过底层的协议(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
参考资料: https://clojure.atlassian.net/browse/CLJ-1879 (由 gshayban 提供)
...