Consider the following approach to modifying a list:
updateList01[lst_List, test_] :=
Module[{xs = lst}, If[test, xs[[1]] += 1]; xs]
lst = {1, 2, 3}
lst = updateList[lst, True]
The good: all arguments are passed explicitly. The bad: xs and lst are apparently both entirely in memory(?). If that is right, what is the Mathematica idiom to avoid building a (potentially large) second list? (Assume there are many lists that needed to be updated and that actual updating is more complex.) Looking at HoldFirst, it sounds like I might avoid a copy by setting HoldFirst. That is also how I am inclined to read How to modify function argument?. Is that a correct interpretation? But even if one can avoid a copy this way, I'm clearly failing to understand something. The following fails:
SetAttributes[updateList02, HoldFirst]
updateList02[lst_List, test_] := If[test, lst[[1]] += 1]
lst02 = {1, 2, 3}
updateList02[lst02, True] (* Not evaluated? *)
lst02 (* Unchanged *)
How do I fix it?
Holdattribute is preventing MMA from noticing thatlst02is aList, so you're head specification isn't matched, which is why it's not evaluating. You'll also run into a problem because you actually want to modify what is located inlst02, try definingupdateList02[lst_Symbol,test_]:=...what you have. – N.J.Evans Nov 03 '15 at 16:29Symbolplays the role of the pointer here. If you want to check that the object represented by the symbol is a list you should do something likeupdate[lst_Symbol,test_]/;Head[ReleaseHold@lst]==List:= ...your function...– N.J.Evans Nov 03 '15 at 16:46Headdoesn't hold its argument so theReleaseHoldisn't required. – Simon Woods Nov 03 '15 at 16:51lst03=lst02is lazy. However there is one important (and weird) thing: set$HistoryLength = 0before dealing with big arrays! – ybeltukov Nov 03 '15 at 17:16