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: [mg121361] Re: execution model: Function vs. delayed execution
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Mon, 12 Sep 2011 04:21:50 -0400 (EDT)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com
  • References: <201109101130.HAA02552@smc.vnet.net>

Hi Alan,

The real (relevant here) difference between Mathematica and some other
languages that may indeed lead to confusion is in the parameter-passing
semantics. Mathematica's way to pass parameters to functions is
fundamentally different: the parameters are *literally inserted* into the
function's body just before the body gets evaluated. The names of Function's
variables, such as "x" in Function[x,x=1] should not be considered variables
- these are just aliases for *values* of input arguments. Therefore,
operating on these "variables" is exactly equivalent to operating on
parameter *values*, manually inserted into the code. In this sense,
functions act more like macros which combine code from pieces and then let
it execute, than like "normal" functions we are used to in languages like C.
If you want the parameters to be inserted into the body without being first
evaluated, you can use Function[x,body,HoldAll] (or other hold attributes).

Now, with this basic mechanism, Mathematica *imitates* various forms of
parameter-passing. In particular, you can imitate pass-by-reference by
Function-s with Hold attributes. For example, in your case, a function like

fn = Function[var,var=DeleteDuplicates[var],HoldFirst]

*will* do what you want. But the way this works is still fundamentally
different from how the pass-by-reference mechanism works in other
languages.They way fn[x] works is that "x" is being *literally inserted*
into the body of the function *without evaluation* (meaning that we insert
the symbol "x", not its value). So, at first, *exact same code*

x = DeleteDuplicates[x]

is constructed by Function (as if you'd write it manually), and then it
evaluates. Should you have left the Hold-attribute out, and what would have
been inserted would be the *value* of x, so the code Function would generate
for evaluation would be

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

( as was mentioned in the other answer), which of course causes an error
since lists are immutable in Mathematica and can not be assigned a value.

Either way (with or without Hold-attributes), function variables (var here)
disappear before the actual evaluation starts, so you *can not* use them as
local variables (in contrast with C, for example).

So, to summarize:  Function- s  are really code generators, which assemble
code from the body and the literally inserted into the body input arguments
(evaluated or not, depending on the presence of Hold-attributes in
Function). The code is assembled in a macro-like fashion, with local
Function variables playing a role of aliases that disappear once the code is
assembled. In particular, assignments to Function's variables become
assignments to the literally inserted input arguments. The assembled  code
then evaluates. Whether or not such assigments generate errors depends on
whether or not input arguments can be assigned a value, and it is exactly
equivalent to insert them by hand into the body and then ask this question.

Hope this helps.

Regards,
Leonid



On Sat, Sep 10, 2011 at 3:30 PM, 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
>
>
>



  • Prev by Date: Re: Ctrl+Number Shortcuts doesn't work
  • Next by Date: Simplifying Bessel Functions
  • Previous by thread: execution model: Function vs. delayed execution
  • Next by thread: Re: execution model: Function vs. delayed execution