BufBills
BufBills

Reputation: 8113

why clojure conj acts different between vector and map

> (conj [0] 1 2 3)
[0 1 2 3]
> (conj {:a "ei"} {:b "bi"})
{:b "bi", :a "ei"}
>  

See, when it acts on vector, it puts 1,2,3 at end of it. Whereas it put :b "bi" in front of :a map k-v pair Why is this? thanks

Upvotes: 0

Views: 135

Answers (2)

Thumbnail
Thumbnail

Reputation: 13483

You don't have to go as far as maps to get inconsistent behaviour from conj:

(conj [1] 2) ; [1 2]    
(conj (list 1) 2) ; (2 1)

Hash maps have no defined order. But, for any map,

  • the seq of entries will always be the same
  • the vals and keys will be in consistent order.

Thus, for map m,

(= (keys m) (map key m))
(= (vals m) (map val m))
(= m (zipmap (keys m) (vals m)))

Currently, this sequence seems to be independent of insertion order. I tested this on sets by randomly shuffling random integers.

Upvotes: 0

Valentin Waeselynck
Valentin Waeselynck

Reputation: 6061

As with many hashed maps implementations, Clojure's hashed maps do not sort their entries, not retain the order in which they were inserted. This allows for better performance.

Note that conj does not have general ordering semantics either (it has ordering semantics for some concrete types, such as vectors).

Upvotes: 2

Related Questions