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: [mg109229] Re: Nest and Fold don't respect HoldFirst?
  • From: Bill Rowe <readnews at sbcglobal.net>
  • Date: Sun, 18 Apr 2010 05:57:47 -0400 (EDT)

On 4/17/10 at 6:03 AM, arno.proeme at gmail.com (ap) wrote:

>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. >>

I get the same error when I use your code and do:

f[Range@10]

So, problem is Nest evaluates the first time to a list of
numbers and operates on this list rather than the global
variable that has been modified. And since your f will not work
with this type of list the error message gets generated. That is
I see the problem as being using the syntax
var[[2]]=RandomInteger to change the second value.

>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.

This sounds like another way to describe the situation. And when
I think about this, I don't see how Nest could work differently.
If Nest doesn't evaluate its argument, how can the next
iteration evaluate correctly?

I don't understand why you create a local copy of the global
variable you want to change. Instead of writing f as you did why
not write it as:

f:=(myList[[2]]=RandomInteger[Length@myList];myList)

that is write f to operate directly on the global variable to be
modified rather than to operate on a local copy of that
variable. If I write f in this fashion then

Nest[f,myList,3]

works as expected with no error messages.

But frankly, the entire idea of modify global variables in this
manner strikes me as being unwise. I see result as being code
that will be difficult to maintain and debug.



  • Prev by Date: Re: Question on replacementFunction
  • Next by Date: Re: Pade Approximation (further generalizations?---feature request)
  • Previous by thread: Re: Nest and Fold don't respect HoldFirst?
  • Next by thread: Re: Nest and Fold don't respect HoldFirst?