# Set gives an unexpected error message (Set::partw)

Here is a minimal example:

s = 1 /(a + b[3]) + 1 /(2 a + b[3]);
s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}]
s[[4]]
s[[4]] = Sum[s[[4]] /. b[3] -> k, {k, 3}]


Output:

Out[143]= 1/(1 + a) + 1/(2 + a) + 1/(3 + a)
Out[144]= 1/(2 a + b[3])


Set::partw: Part 4 of (1/(1+a)+1/(2+a)+1/(3+a))+1/(2 a+b[3]) does not exist. >>

Out[145]= 1/(1 + 2 a) + 1/(2 + 2 a) + 1/(3 + 2 a)


I could only make the error occur when using Set. As the above code shows, both s[[4]] and Sum[s[[4]] /. b[3] -> k, {k, 3}] are well defined.

I have been struggling with similar errors for days, can someone please explain exactly what is happening behind the scenes?

-
Use ReplacePart[s, 4 -> Sum[s[[4]] /. b[3] -> k, {k, 3}]] – ciao Jan 18 '14 at 11:23
If you evaluate s=s before evaluating s[[4]] = Sum[s[[4]] /. b[3] -> k, {k, 3}], the problem disappears – andre Jan 18 '14 at 12:12
Thanks @rasher, there are a few different workarounds. However they are not optimal and do not behave the same as Part. For ex: ReplaceParts[s,{}-> x] returns s unaltered. – Artur Gower Jan 18 '14 at 12:14
Hi @andre, wow s=s does work, but why!? Thanks – Artur Gower Jan 18 '14 at 12:19
@ArturGower: Well, yes. ReplacePart is a function, so you need to assign the result, as in s=ReplacePart.... I think your issue is just an interesting gotcha - part ([[]]) works on fullform expressions, and s vs s=s (which I noted when trying your code) gives the exact same fullform result. Beats me, perhaps L.S. or M.W. or other wizards will chime in. In any case, IMHO ReplacePart is the way to go working with expressions. – ciao Jan 18 '14 at 12:35

The reason this error occurs is because Set and Part have the Attribute HoldFirst, while functions like Position, which was used to get the position 4, does not have HoldFirst.

To verify, the line

s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}]


adds a parenthesis which does not get evaluated, so

(s//Hold)[[1,4]]
Out[1] = Part::partw: "Part 4 of (1/(1+a)+1/(2+a)+1/(3+a))+1/(2\a+b[3]) does not exist."


where as using Evaluate will distribute the parenthesis (effectively distributing the function Plus)

(s//Evaluate //Hold)[[1,4]]
1/(2 a + b[3])


So as pointed out by @andre executing s=s before s[[4]]= ... would solve the problem.

I thank @andre and @rasher for their contributions.

-
+1 for the analysis - I thought it might be a hold, but was working on answering the bit-flip question elsewhere. Thanks for following up, it's a good example. – ciao Jan 18 '14 at 12:56
You are right : s[[1]] = Sum[s[[1]] /. b[3] -> k, {k, 3}] adds a parenthesis which does not get evaluated. This can be seen if you evaluate Trace[s] : you see transformation of s from a 2 elements expression (with parenthesis) to a 4 elements expression. – andre Jan 18 '14 at 19:14