If I do the following in Mathematica
f[l_] := Module[{}, l[[1]] = Append[l[[1]], 3]; l]
f[{{}, 3}]
I get an error:
Set::setps: "{{},3} in the part assignment is not a symbol. "
Even l={{}, 3};f[l] gets the same error. But I can do f[l_] := Module[{}, {Append[l[[1]], 3],l[[2]]}] or l = {{}, 3}; l[[1]] = Append[l[[1]], 3]; l.
What is your explanation?
There are multiple problems here:
Attempting Part assignment on a non-Symbol, just as the error message states.
Attempting to manipulate a named replacement object as though it were a symbol.
The replacement that takes place in this construct:
Is analogous to that of
With:That is, the substitution is made directly and before evaluation, such that the function
Headnever even sees an objectx. Look what happens with this:This evaluates as:
(5 = 5+2; 5)so not only is assignment to5impossible, but all instances ofxthat appear in the right hand side of:=are replaced with the value of x when it is fed tof. Consider what happens if we try to bypass the assignment problem by using a function with side effects:So our
incrementXfunction is working. But now we try:incrementXdid not fail:Rather, the the value of
xwas5at the time of evaluation off[x]and therefore that is returned.What does work?
What options do we have for things related to what you are attempting? There are several.
1. Use a Hold attribute
We can set a Hold attribute such as
HoldFirstorHoldAllon the function, so that we may pass the symbol name to RHS functions, rather than only its value.We see that both the global value of
x, and thexexpression returned byheldFare changed. Note thatheldFmust be given a Symbol as an argument otherwise you are again attempting{1, 2, 3}[[1]] = 7.2. Use a temporary Symbol
As Arnoud Buzing shows, we can also use a temporary Symbol in
Module.{7, 2, 3}{7, 2, 3}{1, 2, 3}3. Use ReplacePart
We can also avoid symbols completely and just use
ReplacePart:{7, 2, 3}{1, 2, 3}This can be used for modifications rather than outright replacements as well:
{{3}, 3}