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

0 votes
in Collections by

(let [s (-> #{}
          transient
          (conj! (clojure.core/with-meta [-7] {:mynum 0}))
          (conj! (clojure.core/with-meta [-7] {:mynum -1}))
          persistent!)]
  [(meta (s [-7])) (meta (first s))])
=> [{:mynum -1} {:mynum 0}]


basically it looks like the "key" (the value we get by seqing on the set) retains the metadata from the first conj! but the "value" (what we get by calling invoke with the "key") carries the metadata from the second conj!. This does *not* match the behavior if we don't use transients:


(let [s (-> #{}
          (conj (clojure.core/with-meta [-7] {:mynum 0}))
          (conj (clojure.core/with-meta [-7] {:mynum -1})))]
  [(meta (s [-7])) (meta (first s))])
=> [{:mynum 0} {:mynum 0}]


(found playing with zach tellman's collection-check)

5 Answers

0 votes
by

Comment made by: michaelblume

Attached patch demonstrating problem (not a fix)

0 votes
by

Comment made by: michaelblume

More investigation:

The difference between "keys" and "vals" arises from the fact that clojure sets use maps under the covers.

The difference between persistent and transient seems to be because PersistentHashSet.cons short-circuits on contains (https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/PersistentHashSet.java#L97) and ATransientSet.conj does not (https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/ATransientSet.java#L27)

Adding a contains check to ATransientSet.conj makes the behavior consistent and passes the attached test, but I imagine this could cause a performance hit. Thoughts?

0 votes
by

Comment made by: michaelblume

Attached proposed fix -- note that this may cause a performance hit for transient sets.

0 votes
by

Comment made by: michaelblume

Attaching an alternative fix -- instead of doing a contains check on every transient conj, back set.get with entryAt. More invasive but possibly faster.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1615 (reported by michaelblume)
...