3
votes

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.

1

1 Answers

4
votes

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