MathGroup Archive 2011

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

Search the Archive

Re: execution model: Function vs. delayed execution

  • To: mathgroup at smc.vnet.net
  • Subject: [mg121342] Re: execution model: Function vs. delayed execution
  • From: "Oleksandr Rasputinov" <oleksandr_rasputinov at hmamail.com>
  • Date: Sun, 11 Sep 2011 07:30:00 -0400 (EDT)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <j4fhvn$2gr$1@smc.vnet.net>

On Sat, 10 Sep 2011 12:34:15 +0100, Alan <alan.isaac at gmail.com> wrote:

> Warning: I am a Mathematica newbie and not a CS type, so my vocabulary  
> may prove clumsy.
>
> 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?
>
> Thanks,
> Alan Isaac
>

Function employs strict lexical scoping that overrides the HoldFirst  
attribute of Set:

In[1] :=
Function[x, x = DeleteDuplicates[x]; x][{1, 1, 2}] // Trace

Out[1] =
{
  Function[x, x = DeleteDuplicates[x]; x][{1, 1, 2}],
  {1, 1, 2} = DeleteDuplicates[{1, 1, 2}]; {1, 1, 2},
  {
   {
    DeleteDuplicates[{1, 1, 2}],
    {1, 2}
   },
   {1, 1, 2} = {1, 2}, (* <- this gives rise to the message *)
   {
    Message[Set::shape,{1, 1, 2},{1, 2}],
    {Set::shape,Lists `1` and `2` are not the same shape.}
    << extra tracing omitted >>
   }
  }
}

this is documented via the statement,

"Function has attribute HoldAll. The function body is evaluated only after  
the formal parameters have been replaced by arguments."

Using With for comparison:

In[2] :=
With[{x = {1, 1, 2}},
  x = DeleteDuplicates[x]; x
]

During evaluation of In[2] :=
Set::shape: Lists {1, 1, 2} and {1, 2} are not the same shape.

Out[2] = {1, 1, 2}

This is in contrast to Block which implements dynamic scoping (or indeed  
Module, whose scoping is effectively lexical, but not as directly so as  
that of With or Function):

In[3] :=
Block[{x = {1, 1, 2}},
  x = DeleteDuplicates[x]; x
]

Out[3] = {1, 2}




  • Prev by Date: Re: execution model: Function vs. delayed execution
  • Next by Date: Re: help to make code run faster (mathematica v8.01)
  • Previous by thread: Re: execution model: Function vs. delayed execution
  • Next by thread: Re: execution model: Function vs. delayed execution