<< Back to previous view

[CLJ-1170] conj-ing x on equal values should produce equal results Created: 23/Feb/13  Updated: 01/Mar/13  Resolved: 01/Mar/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Irakli Gozalishvili Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: None


I've recently have run into a WHAT behavior here is an example:

(def head 1)
(def tail [2 3])

(= tail (rest (cons head tail))) ; true

;; Types don't really match but close enough I guess
(type tail) ; clojure.lang.PersistentVector
(vector? tail) ; true
(type (rest (cons head tail))) ; clojure.lang.PersistentVector$ChunkedSeq
(vector? (rest (cons head tail))) ; false

;; Bet then it get's ugly (I would expect them to be equal)
(= (conj tail :x) (conj (rest (cons head tail)) :x)) ; false

;; Because
(conj tail :x) ; [2 3 :x]
(conj (rest (cons head tail)) :x) ;(:x 2 3)

This brings me to a pretty surprising behavior, which is conj-ing
equal values produce non-equal results:

(= '(2 3) [2 3]) ; true
(= (conj '(2 3) 1) (conj [2 3] 1))

I think conj should either produce equal results or list and vectors with
same elements should not be equal. That would also resolve a previous
problem, although intuitively I would expect `(rest (cons x y))` to
return `y` back.

Comment by Andy Fingerhut [ 24/Feb/13 10:46 AM ]

Irakli, it is an explicitly documented feature that conj puts new items in different places for lists (at the beginning) and vectors (at the end). rest is explicitly documented to call seq on its argument. See their doc strings.

I don't know if it is explicitly documented, or just long-standing practice, that vectors and seqs with the the same sequence of values in them are equal. I think that a lot of existing code would break if Clojure changed so those were not equal.

Generated at Wed Apr 16 08:41:05 CDT 2014 using JIRA 4.4#649-r158309.