简体   繁体   中英

Clojure: Conversion from ArrayMap to HashMap

I'm looking into the clojure source code. The Implementation of PersistentArrayMap has this conditional in the assoc function:

    if(array.length >= HASHTABLE_THRESHOLD)
        return createHT(array).assoc(key, val);

Where HASHTABLE_THRESHOLD is 16. So assoc should return a PersistentHashMap if the arraymap already has 8 pairs. Now look at this clojure code:

(defn create [n, init] (if (= n 0) init (recur (dec n) (assoc init n n))))
(type (create 9 {}))

The output is clojure.lang.PersistentArrayMap , shouldn't it be a PersistentHashMap ? Which is what I get if I use 10 instead of 9.

This is a bug with assoc that's fixed in Clojure 1.10: https://dev.clojure.org/jira/browse/CLJ-1587 in this commit (never mind that the commit is 4 years old).

The bug only affected assoc , so some other ways of producing 9-key maps weren't affected:

Clojure 1.9.0
(type {9 9, 8 8, 7 7, 6 6, 5 5, 4 4, 3 3, 2 2, 1 1})
=> clojure.lang.PersistentHashMap
(type (into {} (map vector (range 9) (range 9))))
=> clojure.lang.PersistentHashMap

After the fix:

Clojure 1.10.0-beta4
(type (create 9 {}))
=> clojure.lang.PersistentHashMap

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM