QUESTION
I have been working on picking expressions apart using Head
and Part
and encountered a little mystery. Consider the canonical example
a + b + c
which has FullForm
Plus[a, b, c]
We expect, then, (a+b+c)[[0]] === Plus === Head[a+b+c]
to be True
, and it is. But then, we would expect (a+b+c)[[1;;3]]
would be {a, b, c}
, wouldn't we? But it isn't. The following is true:
(a + b + c)[[1;;3]] === (a + b + c)
Somehow, [[1;;3]]
, which is supposed to pick off elements 1
through 3
of its argument and put them in a List
, doesn't get rid of the Head
, which is element 0
!
The questions are, then (and I will be grateful for hints and answers!)

Why doesn't
(a + b + c)[[1;;3]]
get rid of(a + b + c)[[0]]
, theHead
? 
What is the right way to get rid of the
Head
? 
(a + b + c)[[0;;3]]
produces0
. I would expect it to produce{Plus, a, b, c}
. Instead, it produces0
. This just deepens the mystery for me! Why?
ANSWER
Point #1
Part
always wraps element sequences with the original head of the expression.
expr = Hold[1 + 1, 2 + 2, 3 + 3, 4 + 4, 5 + 5];
expr[[{2, 3}]]
Hold[2 + 2, 3 + 3]
For this purpose a single part e.g. 1
is not a sequence but {1}
and 1 ;; 1
are:
expr[[1]]
expr[[{1}]]
expr[[1 ;; 1]]
2 Hold[1 + 1] Hold[1 + 1]
This applies at every level of the extraction:
expr = g[h[1, 2], i[3, 4]];
expr[[ 2 , 1 ]]
expr[[ {2}, 1 ]]
expr[[ 2 ,{1} ]]
expr[[ {2},{1} ]]
3 g[3] i[3] g[i[3]]
I used this nontrivially for Elegant manipulation of the variables list.
Point #2
Consider instead using Extract
which wraps sequences in List
:
Extract[expr, {{2}, {3}}]
{4, 6}
The third argument of Extract
can be used to specify a function to apply to individual elements before they are evaluated:
Extract[expr, {{2}, {3}}, HoldForm]
{2 + 2, 3 + 3}
If you want all parts you can also use Level
:
Level[(a + b + c), {1}, Heads > True]
{Plus, a, b, c}
Or Cases
:
Cases[(a + b + c), _, Heads > True]
{Plus, a, b, c}
Or Replace
/ReplaceAll
:
(a + b + c) /. head_[body___] :> {head, body}
{Plus, a, b, c}
Point #3
The last point is more tricky and I had to check it myself. There is a behavior that I also did not expect:
Range[5][[0 ;; 5]]
{}
What I expected was an error as seen here:
Range[5][[0 ;; 4]]
and here:
Range[5][[0 ;; 6]]
When Span
is used in Part[x, 0 ;; n]
where n
is the length of x
, Part
returns the head of the expression. Therefore (a + b + c)[[0;;3]]
returns Plus[]
and Plus[]
evaluates to 0
.
I believe Span
behaves this way because of how it handles nonpositive values, and zerolength spans. Consider:
Range[10][[2 ;; 10]]
{9, 10}
You can see that it wraps around. Now consider:
Range[10][[5 ;; 4]]
{}
An empty span returns the head of the expression with no arguments.
Using 0 ;; n
where n
is the last element in the list, or 0 ;; 1
, is also an empty span wrapping around the open end of the list.
Range[10][[0 ;; 1]]
Tweet{}