assoc / dissoc consistency, maps and vectors

293 views
Skip to first unread message

vra...@gmail.com

unread,
Nov 2, 2013, 2:03:19 PM11/2/13
to clo...@googlegroups.com
I realize `dissoc` isn't implemented to work on vectors for technical reasons (such as explained on 1/13/11 here https://groups.google.com/forum/#!msg/clojure/Lx9ysZ4ndfw/E52rVTvclMoJ ).

"It'd be nice" if it did as I still get surprised by this on occasion, it feels like an inconsistency when using Clojure such that I'd imagine it's a general point of frustration for others as well.


(assoc [1 2 3] 1 'a)
;=> [1 a 3]

(dissoc ['a 'b 'c] 1)
;=> ClassCastException clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap  clojure.lang.RT.dissoc (RT.java:759)


(assoc-in [['a 'b] ['c 'd]] [1 1] 'x)
;=> [[a b] [c x]]

(clojure.core.incubator/dissoc-in [['a 'b] ['c 'd]] [1 1])
;=> ClassCastException clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap  clojure.lang.RT.dissoc (RT.java:759)

Andy Fingerhut

unread,
Nov 2, 2013, 2:16:42 PM11/2/13
to clo...@googlegroups.com
What would you expect the return value of (dissoc ['a 'b 'c] 1) to be?


--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

vra...@gmail.com

unread,
Nov 2, 2013, 2:51:01 PM11/2/13
to clo...@googlegroups.com


On Saturday, November 2, 2013 1:16:42 PM UTC-5, Andy Fingerhut wrote:
What would you expect the return value of (dissoc ['a 'b 'c] 1) to be?

Hi Andy,

Thanks for your interest! This is the "ideal" behavior I would expect from dissoc, for consistency with assoc:


(assoc ['a 'b 'c] 1 'x)
;=> ['a 'x 'c]


(dissoc ['a 'b 'c] 1)
;=> ['a 'c]



(assoc-in [['a 'b] ['c 'd]] [1 1] 'x)
;=> [[a b] [c x]]

(clojure.core.incubator/dissoc-in [['a 'b] ['c 'd]] [1 1])
;=> [[a b] [c]]


 

Ben Wolfson

unread,
Nov 2, 2013, 3:20:40 PM11/2/13
to clo...@googlegroups.com
On Sat, Nov 2, 2013 at 11:51 AM, <vra...@gmail.com> wrote:



(dissoc ['a 'b 'c] 1)

;=> ['a 'c]

So then (get (dissoc some-vector i) i) would be equivalent to (get some-vector (inc i))?

--
Ben Wolfson
"Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure." [Larousse, "Drink" entry]

vra...@gmail.com

unread,
Nov 2, 2013, 3:38:57 PM11/2/13
to clo...@googlegroups.com


On Saturday, November 2, 2013 2:20:40 PM UTC-5, Ben wrote:
So then (get (dissoc some-vector i) i) would be equivalent to (get some-vector (inc i))?

(def some-vector ['a 'b 'c 'd 'e])

(assoc some-vector 0 'x)
;=> [x b c d e]
(dissoc some-vector 0) ;; proposed
;=> [b c d e]

(assoc some-vector 1 'x)
;=> [a x c d e]
(dissoc some-vector 1) ;; proposed
;=> [a c d e]

(assoc some-vector 2 'x)
;=> [a b x d e]
(dissoc some-vector 3) ;; proposed
;=> [a b d e]


(def some-map {0 'a 1 'b 2 'c 3 'd 4 'e})

(assoc some-map 0 'x)
;=> {0 x, 1 b, 2 c, 3 d, 4 e}
(dissoc some-map 0)
;=> {1 b, 2 c, 3 d, 4 e}

(assoc some-map 1 'x)
;=> {0 a, 1 x, 2 c, 3 d, 4 e}
(dissoc some-map 1)
;=> {0 a, 2 c, 3 d, 4 e}

(assoc some-map 2 'x)
;=> {0 a, 1 b, 2 x, 3 d, 4 e}
(dissoc some-map 2)
;=> {0 a, 1 b, 3 d, 4 e}

vra...@gmail.com

unread,
Nov 2, 2013, 3:40:37 PM11/2/13
to clo...@googlegroups.com


On Saturday, November 2, 2013 2:38:57 PM UTC-5, vra...@gmail.com wrote:
(assoc some-vector 2 'x)
;=> [a b x d e]
(dissoc some-vector 3) ;; proposed
;=> [a b d e]

Typo:


(assoc some-vector 2 'x)
;=> [a b x d e]
(dissoc some-vector 2) ;; proposed

Jozef Wagner

unread,
Nov 2, 2013, 5:56:13 PM11/2/13
to clo...@googlegroups.com
Problem is, when your proposed dissoc removes value from a vector, it shifts all larger keys. So dissoc would not only remove value at index position, but also change keys for pther values. And this is not what dissoc should do

user=> (map-indexed vector [:a :b :c :d])
([0 :a] [1 :b] [2 :c] [3 :d])
user=> (dissoc [:a :b :c :d] 1) ;; your proposal
[:a :c :d]
user=> (map-indexed vector [:a :c :d])
([0 :a] [1 :c] [2 :d])

JW

vra...@gmail.com

unread,
Nov 2, 2013, 6:12:56 PM11/2/13
to clo...@googlegroups.com


On Saturday, November 2, 2013 4:56:13 PM UTC-5, Jozef Wagner wrote:
Problem is, when your proposed dissoc removes value from a vector, it shifts all larger keys. So dissoc would not only remove value at index position, but also change keys for pther values. And this is not what dissoc should do


You're right. I'm not sure why this is suddenly clear without essentially any new information. :) I think I had the wrong conceptual impression of what assoc and dissoc should be, putting the emphasis on the generality of the collection types instead its specificity to the indicies.

For my notion of assoc/dissoc to hold parity, it would have to work like this which seems undesirable:



(def some-vector ['a 'b 'c 'd 'e])
(def some-map {0 'a 1 'b 2 'c 3 'd 4 'e})


(assoc some-vector 2 'x)
;=> [a b x d e]
(dissoc some-vector 2) ;; theoretical
;=> [a b d e] ;; theoretical


(assoc some-map 2 'x)
;=> {0 a, 1 b, 2 x, 3 d, 4 e}
(dissoc some-map 2)
;=> {0 a, 1 b, 2 d, 3 e} ;; not good

Jozef Wagner

unread,
Nov 3, 2013, 7:30:09 AM11/3/13
to clo...@googlegroups.com
You also assume keys are comparable or that 'conj order' is retained, which is often not true. Consider following map:

(your-dissoc {2 1, :a 1, "foo" 1, 'bar 1} 2)
=> ????

Vectors are indexed and maps are associative. These two concepts share some functionalities (assoc, get), but are otherwise very different.

JW


--
Reply all
Reply to author
Forward
0 new messages