Share your thoughts in the 2021 Clojure Community Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

I was under the assumption that {:keys [a b c d]} was destructured in the order of a->b->c->d which is proven below

haystack.core=> (clojure.pprint/pprint (destructure '[{:keys [a b c d] :as options} {}]))
[map__14131
 {}
 map__14131
 (if
  (clojure.core/seq? map__14131)
  (clojure.lang.PersistentHashMap/create (clojure.core/seq map__14131))
  map__14131)
 options
 map__14131
 a
 (clojure.core/get map__14131 :a)
 b
 (clojure.core/get map__14131 :b)
 c
 (clojure.core/get map__14131 :c)
 d
 (clojure.core/get map__14131 :d)]
nil

however, when the keys vector has elements > 10, the order changes all of a sudden

haystack.core=> (clojure.pprint/pprint (destructure '[{:keys [a b c d e f g h i j] :as options} {}]))
[map__14137
 {}
 map__14137
 (if
  (clojure.core/seq? map__14137)
  (clojure.lang.PersistentHashMap/create (clojure.core/seq map__14137))
  map__14137)
 options
 map__14137
 i
 (clojure.core/get map__14137 :i)
 a
 (clojure.core/get map__14137 :a)
 e
 (clojure.core/get map__14137 :e)
 c
 (clojure.core/get map__14137 :c)
 g
 (clojure.core/get map__14137 :g)
 j
 (clojure.core/get map__14137 :j)
 h
 (clojure.core/get map__14137 :h)
 b
 (clojure.core/get map__14137 :b)
 d
 (clojure.core/get map__14137 :d)
 f
 (clojure.core/get map__14137 :f)]
nil

I couldn't find anything in the destructure source code

2 Answers

+1 vote
by

The order of keys destructuring is undefined and you should not rely on this. See also https://github.com/borkdude/clj-kondo/issues/916.

by
yes we concluded in our discussion that we won't rely on it
0 votes
by

Maps are unordered. Maps with 8 or fewer keys use PersistentArrayMap which happens to retain order, maps with more keys use PersistentHashMaps which do not retain order.

...