Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 749
saga Avatar asked Apr 07 '26 18:04

saga


1 Answers

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
like image 58
Taylor Wood Avatar answered Apr 10 '26 08:04

Taylor Wood



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!