Re: execution model: Function vs. delayed execution

*To*: mathgroup at smc.vnet.net*Subject*: [mg121353] Re: execution model: Function vs. delayed execution*From*: Daniel Lichtblau <danl at wolfram.com>*Date*: Mon, 12 Sep 2011 04:20:17 -0400 (EDT)*Delivered-to*: l-mathgroup@mail-archive0.wolfram.com

----- Original Message ----- > From: "Bill Rowe" <readnews at sbcglobal.net> > To: mathgroup at smc.vnet.net > Sent: Sunday, September 11, 2011 6:29:49 AM > Subject: Re: execution model: Function vs. delayed execution > On 9/10/11 at 7:30 AM, alan.isaac at gmail.com (Alan) wrote: > > >I am used to a deferred execution model of function definition. > >Roughly, if I can write code that would be successfully executed > >outside a function definition, then I can make it a function body by > >appropriately "wrapping" it. > > >In Mathematica, I can evaluate the following): > >x = {1,1,2} > >x=DeleteDuplicates[x]; x > >(Note: the redundancy is intentional.) > > >Next, I attempt to "wrap" this as follows > >Clear[x] > >Function[x, (x=DeleteDuplicates[x];x)][{1,1,2}] > > >This produces an error: Set::shape: "Lists {1,1,2} and {1,2} are not > >the same shape." > > >Can you help me understand the execution model that leads to this? > > The code > > Function[x, (x=DeleteDuplicates[x];x)][{1,1,2}] > > has x playing two roles, as a formal argument to the function > and to hold the result. Mathematica attempts to evaluate the > function body by replacing x with the {1,1,2} wherever x > appears. This results in attempting to evaluate > > {1,1,2}=DeleteDuplicates[{1,1,2}] > > which is what generates the error message. Adding a new variable > to the code, i.e., > > Function[x, (y=DeleteDuplicates[x];y)][{1,1,2}] > > eliminates the problem and error message. Or more simply, > > Function[x, DeleteDuplicates[x]][{1,1,2}] > > Obviously, this last eliminates the redundancy which you state > was intentional. Another alternative would be to have the function hold its argument, and pass it the symbol rather than value. In[273]:= x = {1, 1, 2}; In[274]:= Function[x, x = DeleteDuplicates[x]; x, HoldFirst][x] Out[274]= {1, 2} This has the effect of changing the value of symbol x, not just returning the altered value. That is to say, we have in effect a call-by-reference rather than call-by-value. In[275]:= x Out[275]= {1, 2} Which method should be used would depend on whether or not altering the value of x was a desired outcome. Daniel Lichtblau Wolfram Research