MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Nest and Fold don't respect HoldFirst?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg109238] Re: Nest and Fold don't respect HoldFirst?
  • From: Bob Hanlon <hanlonr at cox.net>
  • Date: Sun, 18 Apr 2010 05:59:25 -0400 (EDT)

mylist = Range[10];

SetAttributes[{f, f1, f2}, HoldFirst];

f[var_] := Module[{x = var},
   {x[[2]] = RandomInteger[{0, Length[x]}], x}[[2]]];

Nest[f, mylist, 3]

{1,4,3,4,5,6,7,8,9,10}

f1[var_] := Module[{x = var},
   x[[2]] = RandomInteger[{0, Length[x]}];
   x];

Nest[f1, mylist, 3]

{1,1,3,4,5,6,7,8,9,10}

f2[var_] := ReplacePart[var,
   2 -> RandomInteger[{0, Length[var]}]];

Nest[f2, mylist, 3]

{1,6,3,4,5,6,7,8,9,10}


Bob Hanlon

---- ap <arno.proeme at gmail.com> wrote: 

=============
Dear group,

I just wanted to check that I'm correct in thinking that I cannot use
Nest or Fold to iterate a function, where that function has a
HoldFirst attribute set that allows it to modify the global variable
(parameter) passed to it.
As a test case / example I define a function which modifies a global
variable (a list) by setting the 2nd element to a random integer, and
returns the modified list, as follows:

SetAttributes[f,HoldFirst]
f[var_] := {var[[2]] = RandomInteger[ {0,Length[var]} ], var}[[2]]

Then if I simply do

mylist=Range[10]
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

I get

f[mylist]
{1, 8, 3, 4, 5, 6, 7, 8, 9, 10}

as expected.
However, if I try to Nest this function to apply it iteratively (as an
alternative to a For or Do loop), as follows:

Nest[f, mylist, 3]

I get

Set::setps: {1,2,3,4,5,6,7,8,9,10} in the part assignment is not a
symbol. >>

In other words, Nest seems not to respect the HoldFirst attribute of
f. Instead, the list is passed by value and the resulting attempted
assignment of the random integer fails. The same behaviour results
from Fold if I slightly modify f to make it a function of two
variables.

Is this correct? And if so, is the best alternative simply to use a
loop? That's easy enough, but I was just trying to be as 'functional'
and hence efficient as possible, as this kind of modification of a
global variable is a key step in my algorithm and needs to be as fast
as possible. I have an alternative implementation where instead of
trying to modify the list I Join existing parts of it with the
relevant modified element, but this appears to be ~25% slower than a
simple Do loop to modify the list.



  • Prev by Date: Re: Nest and Fold don't respect HoldFirst?
  • Next by Date: Re: Question on replacementFunction
  • Previous by thread: Re: Nest and Fold don't respect HoldFirst?
  • Next by thread: Re: Nest and Fold don't respect HoldFirst?