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?
Hold
attribute is preventing MMA from noticing thatlst02
is 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
. $\endgroup$ – N.J.Evans Nov 3 '15 at 16:29Head
doesn't hold its argument so theReleaseHold
isn't required. $\endgroup$ – Simon Woods Nov 3 '15 at 16:51lst03=lst02
is lazy. However there is one important (and weird) thing: set$HistoryLength = 0
before dealing with big arrays! $\endgroup$ – ybeltukov Nov 3 '15 at 17:16