about the design of Part related to Association

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]]


gives values

1


while

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1;;2]]


gives

<|"a" -> 1, "b" -> 2|>


I just feel an inconsistency in this kind of Part design.

Why

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]]


doesn't give

"a" -> 1


as

{"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4}[[1]]


gives

"a" -> 1


or as many people point out that functions act transparently on Association's values, why doesn't

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1;;2]]


give

{1,2}


??? Can somebody give an explanation?

• I agree. It is not consistent. May be it is a bug? Commented Dec 13, 2014 at 4:36
• I think I figured it. To obtain the whole part, i.e. (key->value), one must use [[n;;n]] syntax or [[n;;]]. But if you use [[n]] this will only give the value at part n. The reason why [[n;;m]] work for both key,values at both n through m parts, is because of the ;; usage. So to pull both key+value, use ;;, else it will default to only the value at that part. Commented Dec 13, 2014 at 4:55
• @Nasser Yeah, it is definitely not a bug. They designed it in this way! They write these example in the help doc. But it just doesn't consistent with Part of List. Commented Dec 13, 2014 at 4:55
• This behavior has been noted before: (56013) Commented Dec 13, 2014 at 5:15
• Yes, I think as well it is consistent. Observe that for an expression f[x,y,z,u,v,w], the Part function returns an argument only when it is called with a single number, in all other cases, such as 1;;2, {3,2,1}, the result has head f. With Associations, it is almost the same. Part with a number gives the value, in all other cases it gives an Association Commented Dec 13, 2014 at 8:27

IMO the behavior is consistent, and acts like in Lists.

For Lists we have:

{"a", "b", "c", "d"}[[1]]
{"a", "b", "c", "d"}[[{1}]]

"a"
{"a"}


and for Associations:

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]]
<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[{1}]]

1
<|"a" -> 1|>


For for the Spam form ;; the result is always like a list inside Part, so:

<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[{1}]]
<|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1;;1]]


are equivalent.

• I agree, the behaviour of Part with Association is consistent and expected. Commented Dec 13, 2014 at 11:05
• @SimonWoods But why <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]] doesn't give "a" -> 1? Commented Dec 13, 2014 at 12:10
• @matheorem, because the value is not the rule "a"->1, it is just 1. Note that FreeQ[<|"a"->1|>, Rule] is True - there is no Rule in that expression, despite appearances. Commented Dec 13, 2014 at 13:05
• @SimonWoods But the FullForm[<|"a"->1|>] gives Association[Rule["a",1]]. There is Rule. Commented Dec 13, 2014 at 13:14
• @matheorem, there's some discussion of that here. I don't claim to fully understand the situation, but I have found that associations mostly make sense if you regard the values as being what's really there at level 1, and the keys as ephemeral magic labels which are transparent to most operations and which vanish as soon as the value is no longer contained inside an association. Commented Dec 13, 2014 at 13:25