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