Surprising behavior of Part[ ]

Look at this list

list={1,2,3,4}


Obiously

list[[1, 2]]


throws the error:

During evaluation of Part::partd: Part specification {1,2,3,4}[[1,2]] is longer than depth of object.

However:

list[[1,All]]


yields (Mathematica 12 on Windows)

Integer[]


which does not make much sense to me. Moreover, weird constructs like list[[All,All,All,All,All]] do not throw an error.

Can this (at least to me) strange behaviour of the basic command Part[] be explained? (Needless to say, that this is just a simple demonstration of the effect, but it occured during execution a larger program with strange consequences.)

EDIT: I just realized that this question is closely related to mine and adds some more aspects to it.

• Indeed a bit irregular, but not completely derstandable (=ununderstandable ;) - cf list[[1, 0]]. – Henrik Schumacher Apr 29 '19 at 12:46
• There are similar oddities with Span: Consider e[[1 ;; -1]] and e[[2 ;; -1]], with e being 1, f[], and f[1]. – Michael E2 Apr 29 '19 at 14:24

Compare:

17[[All]]
(* Integer[] *)


The evaluation of expr[[All]] should result in h[p1, p2,...] where h is Head[expr] and p1, p2,... is a possibly empty list (not List) of all the parts of expr. An Integer has no parts (because it is atomic), but its head is Integer. Hence we get Integer with an empty argument list.

• Well, I do accept that 17[[All]] returns an Integer[ ], but I am surprised that it does not throw a message, as e.g. xxx[[All]] returns Symbol[ ] but does throw a message. 1.2[[All]] does not as well. – Michael Weyrauch Apr 29 '19 at 15:09
• @MichaelWeyrauch xxx[[All]] does not throw a message. It is Symbol[] that throws the message. It's not Part. – Szabolcs Apr 29 '19 at 17:06

Consider the following example:

We have a list of 3-tuples:

list = {{1,2,3}, {5,4,3}, {9,7,5}, {0,3,8}}


Take the first element of each sublist.

list[[All, 1]]
(* {1,5,9,0} *)


If the list had 4 elements, the result will have 4 elements too. In general, if the list has $$n$$ elements, the result should also have $$n$$ elements. But what if the list is empty, i.e. $$n=0$$? It would be reasonable to get a result with 0 elements, of course. But for that to work, Part needs to be a bit flexible, after all, we can't take the 1st element of nothing ... or can we?

list = {}

list[[All, 1]]
(* {} *)


Well, it works. And it is extremely useful because I do not need to have extra code for these special cases.

This explains why it is okay to add more indexes to Part than the number of levels that the expression has. This is why you can have 10 Alls in there. But you could also have list[[All, All, 1, 1]], not just list[[All, All, All, All]]

As for why 1[[All]] is Integer[], Michael has already explained it. My answer is only for explaining why you can have many Alls in there.

• I just wrote code that relies on this yesterday. I find it very useful. – Szabolcs Apr 29 '19 at 17:05