7
<|"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?

matheorem
  • 17,132
  • 8
  • 45
  • 115
  • I agree. It is not consistent. May be it is a bug? – Nasser Dec 13 '14 at 04: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. – Nasser Dec 13 '14 at 04: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. – matheorem Dec 13 '14 at 04:55
  • @Nasser <|"a" -> 1, "b" -> 2|>[[{1, 2}]] also behaves as Span does. My guess is that the creator assumed that someone who uses Span is collecting several elements. i.e. the intention is to make this change when the user requests more than one element. – C. E. Dec 13 '14 at 05:04
  • @Nasser I think this inconsistency is awkward. It declares that there is a special case in using Part in Association, not elegant. What do you think? – matheorem Dec 13 '14 at 05:04
  • I found more documentation on part with association. it is all here http://reference.wolfram.com/language/ref/Part.html about half way down the page. many examples. – Nasser Dec 13 '14 at 05:10
  • 3
    This behavior has been noted before: (56013) – C. E. Dec 13 '14 at 05:15
  • I guess it is consistent. check <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[;;1]] and <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[;;2]]. and also <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]] and <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[2]] – Basheer Algohi Dec 13 '14 at 08:00
  • 3
    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 – Fred Simons Dec 13 '14 at 08:27
  • With your last question you are misunderstanding the effect of Span. It returns the selected parts wrapped in their original head. So you only get a List back if you are extracting parts from a List. For example f[1, 2, 3][[1;;2]] gives f[1, 2] not {1, 2}. – Simon Woods Dec 13 '14 at 14:32
  • @SimonWoods Well, My last question is actually a question about the transparency of Association. Since assoc[[1]] directly acts on values of assoc, then why doesn't assoc[[span]] gives collection of values? I admit I made a mistake. Like you said, original head should be preserved. Then, <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1;;2]] should give <|1,2|>, but this is not an association!It is a contradiction! So they must make it as <|"a" -> 1, "b" -> 2|>. Wow, maybe this is what the creators of Association thought in their mind!!! You enlightened me!:) What do you think? – matheorem Dec 13 '14 at 14:48

1 Answers1

7

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.

Murta
  • 26,275
  • 6
  • 76
  • 166
  • 1
    I agree, the behaviour of Part with Association is consistent and expected. – Simon Woods Dec 13 '14 at 11:05
  • @SimonWoods But why <|"a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4|>[[1]] doesn't give "a" -> 1? – matheorem Dec 13 '14 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. – Simon Woods Dec 13 '14 at 13:05
  • @SimonWoods But the FullForm[<|"a"->1|>] gives Association[Rule["a",1]]. There is Rule. – matheorem Dec 13 '14 at 13:14
  • 1
    @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. – Simon Woods Dec 13 '14 at 13:25
  • @SimonWoods It still confused me now, and according to Taliesin Beynon's comment, if seems that Association is not mature at present stage, am I right? – matheorem Dec 13 '14 at 13:39
  • @matheorem, it looks like there is still some work to do with pattern matching on Associations, but I wouldn't expect the behaviour with Part to change. – Simon Woods Dec 13 '14 at 14:03