241 views

Skip to first unread message

May 29, 2009, 8:57:24 PM5/29/09

to

This matter is pretty unimportant, but perhaps of interest in laying

out a persistent source confusion for me with Mathematica: evaluation

control.

out a persistent source confusion for me with Mathematica: evaluation

control.

I'm skeptical of the built-in debugger because it seems to crash the

kernel often, so I do most of my debugging by inserting print

statements like

Print["variableOne = ",variableOne].

Being extraordinarily lazy I soon thought it might be nice to have a

little function, say dbgv, which takes a variable or name of a

variable as an argument, and produces the same result as the print

statement above.

At first I assumed this would be easy, since almost every programming

problem turns out to be pretty easy with Mathematica. But after an hour

or so I began to wonder whether it would be possible at all. I did

eventually find a solution, a function dbgv such that dbgv[variableOne]

produces exactly the effect of the print statement, but it's really ugly.

I'll post it later.

Granted this is not an important problem since it's not too much

trouble to just type in the whole print statement. But it's worth

noting that this would trivial to solve with a Lisp macro, and despite

the fantastic expressibility of Mathematica it doesn't seem to have a

good replacement for macros. The closest equivalents are $Pre(Read),

which I used in my solution, but they're not nearly as nice to work with.

Can anyone think of an elegant solution?

May 31, 2009, 6:30:31 AM5/31/09

to

Hi,

the way to do it is to use non-standard evaluation. Here is the function

that probably does what you want

In[1] =

SetAttributes[ShowIt, HoldAll];

ShowIt[code_] :=

Module[{y},

Print[ToString[Unevaluated[code]], " = ", y = code];

y];

This will print the variable name, its value, and then return the variable

value itself so that you can use it in your code, just as before - you just

need to "stick" ShowIt in the place where you need to print the info. The

parameter of the function does not necessarily have to be a variable - you

can wrap it around any piece of code (there could be a few subtleties if

your code also uses non-standard evaluation, but this is rarely the case).

Note that we take care that the code (<code>) is executed only once, so the

case of side effects (like i++ etc) is handled correctly. Example:

In[2] =

Block[{i, res = Table[0, {5}]},

For[i = 1, i <= 5, i++,

res[[i]] = ShowIt[i]];

res]

i = 1

i = 2

i = 3

i = 4

i = 5

Out[2] = {1,2,3,4,5}

>But it's worth

>noting that this would trivial to solve with a Lisp macro, and despite

>the fantastic expressibility of Mathematica it doesn't seem to have a

>good replacement for macros.

This is just not true. The ShowIt function above *is* a macro, since, due to

the HoldAll attribute, it expands the code before it is run. As another very

simple macro example, consider this:

ClearAll[withCodeAfter];

SetAttributes[withCodeAfter,HoldRest];

withCodeAfter[before_,after_]:=(after;before);

This macro can be used to avoid an introduciton of auxilliary variable in

case

when the result is computed somewhere in the middle of the code (by the

<before> piece), but when some other code must be executed (<after> piece),

before the result is returned. Example:

In[3] =

Clear[i];

i = 0;

withCodeAfter[Print[i], i++]

0

In[4] = i

Out[4] = 1

The availability of macros in Mathematica is apparent from the fact that all

the code we write is data as well (as can be seen by the FullForm command),

and the availability of non-standard evaluation. This fact is obscured by

the built-in pretty-printer/preprocessor which allows us to use shortcut and

infix notation.

However indeed there are a few reasons that make macros harder to write in

Mathematica:

a) Evaluator is more complex, than in Lisp. There are several kinds of

global rules, there are attributes, there are several ways to make

evaluation non-standard, there are built-in rules for system functions that

the user may not be aware of, there is dynamic scoping with Block that is

very powerful but can be easily abused, there are several lexical scoping

constructs (Module, With, Function, SetDelayed, etc) and associated with

them rules for variable collision resolution, etc, etc. It is harder to

"compute" the consequences of the macro expansion, or to get it right in all

cases of intended use.

b) Pattern-matching gets in the way when some portion of the code is

rule-based, since evaluation depends on whether or not some patterns match.

c) This is a consequence of b): when we define a function with restricted

patterns such as f[x_Integer]:=... etc, we effectively introduce a (weak)

typing,

which also gets in the way.

d) It requires conscious effort not to use (at all) short-hand and/or infix

notation, which is handy but often hides that the code may expressed as an

expansion of some macro.

I think it will generally be very nice if macros would find their way into

the mainstream Mathematica programming, but this will probably start to

really pay off for those who intend to use Mathematica to build rather

large/complex systems (or their prototypes).

Best regards,

Leonid

On Fri, May 29, 2009 at 5:57 PM, dabr...@indiana.edu

<dabr...@indiana.edu>wrote:

May 31, 2009, 6:30:45 AM5/31/09

to

For a function that works like the Print expression above, one could use

one of the following:

Non-string version:

SetAttributes[dbg, HoldAll]

dbg[var_] := Print[ToString[Unevaluated[var]], " = ", var]

String version:

dbg2[name_String] :=

ToExpression[name, InputForm, Print[name, " = ", #] &]

Though I am not sure I understand your question because I don't see what

relation $Pre or Read have with this.

For debugging, take a look at Trace, On[] and Off[], and Monitor as well.

May 31, 2009, 6:33:24 AM5/31/09

to

Hi,

SetAttributes[printVariable,HoldAll]

printVariable[var_]:=Print[ToString[Unevaluated[var]]," = ",var]

?

Regards

Jens

May 31, 2009, 6:34:20 AM5/31/09

to

SetAttributes[printVariable, HoldAll];

printVariable[var_] := Print[ToString[HoldForm[var]] <> " = " <>

ToString[var]]

printVariable[var_] := Print[ToString[HoldForm[var]] <> " = " <>

ToString[var]]

ape = 1;

printVariable[ape]

Out: ape = 1

Cheers -- Sjoerd

On May 30, 2:57 am, "dabro...@indiana.edu" <dabro...@indiana.edu>

wrote:

> This matter is pretty unimportant, but perhaps of interest in laying

> out a persistent source confusion for me with Mathematica: evaluation

> control.

>

> I'm skeptical of the built-in debugger because it seems to crash the

> kernel often, so I do most of my debugging by inserting print

> statements like

>

> Print["variableOne = ",variableOne].

>

> Being extraordinarily lazy I soon thought it might be nice to have a

> little function, say dbgv, which takes a variable or name of a

> variable as an argument, and produces the same result as the print

> statement above.

>

> At first I assumed this would be easy, since almost every programming

> problem turns out to be pretty easy with Mathematica. But after an hou=

May 31, 2009, 6:37:07 AM5/31/09

to

I use this function:

peek = (Print[#1]; #1) &

My programming style is to pipe functions:

x//f1//f2//f3...//fn

so sticking in a //peek is easy.

peek = (Print[#1]; #1) &

My programming style is to pipe functions:

x//f1//f2//f3...//fn

so sticking in a //peek is easy.

Ken Levasseur

http://homepage.mac.com/klevasseur/

On May 29, 2009, at 8:57 PM, dabr...@indiana.edu wrote:

> This matter is pretty unimportant, but perhaps of interest in laying

> out a persistent source confusion for me with Mathematica: evaluation

> control.

>

> I'm skeptical of the built-in debugger because it seems to crash the

> kernel often, so I do most of my debugging by inserting print

> statements like

>

> Print["variableOne = ",variableOne].

>

> Being extraordinarily lazy I soon thought it might be nice to have a

> little function, say dbgv, which takes a variable or name of a

> variable as an argument, and produces the same result as the print

> statement above.

>

> At first I assumed this would be easy, since almost every programming

> problem turns out to be pretty easy with Mathematica. But after an

> hour

May 31, 2009, 6:37:18 AM5/31/09

to

Thanks a lot to Leonid, Szabolcs, and Ken for their solutions. I

liked Leonid's the best, being both much simpler and more general than

mine.

liked Leonid's the best, being both much simpler and more general than

mine.

SetAttributes[ShowIt, HoldAll];

ShowIt[code_] :=

Module[{y},

Print[ToString[Unevaluated[code]], " = ", y = code];

y];

My own solution was the hideous

$PreRead=ReplaceAll[#,{{"dbgv","[",var_,"]"}:>{"Print","[",RowBox

[{"\""<>var<>" = "<>"\"",",",var}],"]"}}]&;

which makes dbgv work like a macro. The grotesqueness is because what

$PreRead sees is a very raw input form, with expressions broken down

into RowBox's. In a sense this is the most direct analog to Lisp's

macros, but ... yechh.

The Unevaluated[] function had slipped off my radar, probably because

I never fully grokked the distinction between it and Hold[]. In fact

I'm still a bit confused about it. At first I thought it might like

the evaluation inhibitor ` in Lisp, but some examples disabused me of

that.

In[2]:= f@Unevaluated[5 + 6 + 7 + 8]

Out[2]= f[Unevaluated[5 + 6 + 7 + 8]]

In[11]:= ToString@Unevaluated[5 + 6 + 7 + 8]

Out[11]= "5 + 6 + 7 + 8"

I might have expected Out[11]= "Unevaluated[5 + 6 + 7 + 8]"

In[13]:= sqr[x_] := x^2

In[14]:= sqr@Unevaluated[5 + 6 + 7 + 8]

Out[14]= 676

I might have expected Out[14]= sqr[5 + 6 + 7 + 8] since sqr does not

know what to do with the pattern _+_+_+_ or _+_ for that matter.

Could anyone elucidate this for me?

Jun 1, 2009, 7:05:56 AM6/1/09

to

On May 31, 1:37 pm, "dabro...@indiana.edu" <dabro...@indiana.edu>

wrote:

>

> The Unevaluated[] function had slipped off my radar, probably because

> I never fully grokked the distinction between it and Hold[]. In fact

> I'm still a bit confused about it. At first I thought it might like

> the evaluation inhibitor ` in Lisp, but some examples disabused me of

> that.

>

> In[2]:= f@Unevaluated[5 + 6 + 7 + 8]

>

> Out[2]= f[Unevaluated[5 + 6 + 7 + 8]]

>

> In[11]:= ToString@Unevaluated[5 + 6 + 7 + 8]

>

> Out[11]= "5 + 6 + 7 + 8"

>

> I might have expected Out[11]= "Unevaluated[5 + 6 + 7 + 8]"

>

> In[13]:= sqr[x_] := x^2

>

> In[14]:= sqr@Unevaluated[5 + 6 + 7 + 8]

>

> Out[14]= 676

>

> I might have expected Out[14]= sqr[5 + 6 + 7 + 8] since sqr does not

> know what to do with the pattern _+_+_+_ or _+_ for that matter.

> Could anyone elucidate this for me?

wrote:

>

> The Unevaluated[] function had slipped off my radar, probably because

> I never fully grokked the distinction between it and Hold[]. In fact

> I'm still a bit confused about it. At first I thought it might like

> the evaluation inhibitor ` in Lisp, but some examples disabused me of

> that.

>

> In[2]:= f@Unevaluated[5 + 6 + 7 + 8]

>

> Out[2]= f[Unevaluated[5 + 6 + 7 + 8]]

>

> In[11]:= ToString@Unevaluated[5 + 6 + 7 + 8]

>

> Out[11]= "5 + 6 + 7 + 8"

>

> I might have expected Out[11]= "Unevaluated[5 + 6 + 7 + 8]"

>

> In[13]:= sqr[x_] := x^2

>

> In[14]:= sqr@Unevaluated[5 + 6 + 7 + 8]

>

> Out[14]= 676

>

> I might have expected Out[14]= sqr[5 + 6 + 7 + 8] since sqr does not

> know what to do with the pattern _+_+_+_ or _+_ for that matter.

> Could anyone elucidate this for me?

Unevaluated[] is treated in a special way during evaluation. There's

a good explanation of what it does in the docs, under 'More

information':

"f[Unevaluated[expr]] effectively works by temporarily setting

attributes so that f holds its argument unevaluated, then evaluating f

[expr]."

http://reference.wolfram.com/mathematica/ref/Unevaluated.html

There's also a very detailed explanation somewhere in the docs of how

exactly expressions are evaluated by the kernel. You can look that up

if you're interested.

It's no wonder if you're confused about Unevaluated/Hold/etc. and

evaluation order. They can be confusing. People are usually pointed

to the paper titled 'Working with Unevaluated Expressions' by Robby

Villegas. There's a link to it here:

Jun 1, 2009, 7:11:14 AM6/1/09

to

SetAttributes[echo, HoldFirst]

echo[x_] := Print[ToString@HoldForm@x, " = ", x]

Bobby

On Fri, 29 May 2009 19:57:49 -0500, dabr...@indiana.edu

<dabr...@indiana.edu> wrote:

Jun 2, 2009, 6:39:33 AM6/2/09

to

Hi,

Just to add some more to the reply of Szabolcs:

The evaluation process in Mathematica is recursive, going first "down" to

leaves, then evaluating it "up", starting from leaves and going to larger

sub-expressions, checking for the global rules to match. Unevaluated is

treated in a special way in that it suppresses the evaluation of expression

"on the way down", allowing the rules attached to the head (say <g>)

surrounding it to apply "on the way up" on the original expression. The

original expression may or may not evaluate later, depending on what <g>

does with its argument. In the following example:

In[1] =

g[x_ + y_] := x*y;

g[Unevaluated[5 + 5]]

Out[1] = 25,

the rule attached to <g> did apply since the expression 5+5 was preserved in

its unevaluated form. In this case, the original expression (Plus operator)

never evaluated, but in some other cases it may evaluate - it all depends

on <g> now. But without Unevaluated, <g> would never have a chance to see

the original expression, since by the time evaluation goes "up" to g, 5+5

would have evaluated to 10 already. This situation indeed is precisely as if

we would give <g> Hold attribute "on the way down" and remove it "on the way

up".

There are several differences between Hold and Unevaluated. Technically,

Hold is just a wrapper with a HoldAll attribute which is not particularly

different from any user-defined HoldAll wrapper, and is special just because

it is the "official" holding wrapper and there are commands such as

ReleaseHold that work with it together. Most of the functionality of Hold

can pretty much be duplicated/reproduced by any HoldAll wrapper. OTOH,

Unevaluated is one of the "magic symbols", along with Evaluate and Sequence.

It is more deeply "wired in", into the main evaluation loop algorithm, and

its functionality can not be removed, blocked or duplicated. In particular,

we may block Hold with a Block trick Block[{Hold},...], but we can not block

Unevaluated in the same way.

Another difference is that (one level of wrapping with) Unevaluated does not

by itself represent extra level of wrapping - it is automatically stripped

off when the evaluator comes to apply the rules to expression inside it. Not

so with Hold - it is a normal wrapper.

>From the viewpoint of the user, the uses of Hold and Unevaluated are also

different. Hold is often used to preserve the internal expression

unevaluated for more than one successive evaluation (or in between such

evaluations). For example, if one function (say <f>) produces the result as

an expression which wil normally evaluate but whose evaluation we want to

prevent, and another function (say <h>) needs to consume this result in this

unevaluated form, but the result is not passed directly from <f> to <h>,

then <f> may wrap the result in Hold and <h> will then have to unwrap it.

Unevaluated would not help us here since it is normally used in a single

evaluation. Here is a simple example:

In[2] =

Clear[f,h];

f[x_] := Module[{y}, y = Hold[x^2]];

h[x_Hold] := x /. Hold[a_^b_] :> {a, b}

In[3] = odd = Select[f /@ Range[10], Not[FreeQ[#, _?OddQ]] &]

Out[3] = {Hold[1^2], Hold[3^2], Hold[5^2], Hold[7^2], Hold[9^2]}

In[4] = h /@ odd

Out[4] = {{1, 2}, {3, 2}, {5, 2}, {7, 2}, {9, 2}}

What happens here is that <f> constructs some power (square) while <h>

deconstructs it to base-power pair. But <h> is not called directly on the

result of <f>, so we need to prevent expressions from evaluation in between

evaluations involving <f> and <h>. Unevaluated would not be helpful here.

Another thing worth mentioning (and more directly relevant to your example)

is the mechanics of argument - passing. Consider this function:

In[5] =

Clear[f];

f[x_] := {Hold[x],Head[x]};

It is supposed to return the held input together with its head . Let us try

In[6] = (Print["Just before calling f"]; f[#]) &[Print["*"]]

*

Just before calling f

Out[6]= {Hold[Null],Symbol}

If we attempt to force it to not evaluate the argument (Printing), in this

way:

In[7] = Function[y, (Print["Just before calling f"]; f[y]),

HoldAll][Print["*"]]

Just before calling f

*

Out[7]= {Hold[Null],Symbol}

We see that the result was indeed not evaluated before having been passed to

<f>, but it was evaluated in <f>, and the r.h.s of <f> uses an already

evaluated result. Now, it is to prevent also this evaluation of the

argument that we need Unevaluated:

In[8] =

Function[y, (Print["Just before calling f"]; f[Unevaluated[y]]),

HoldAll][Print["*"]]

Just before calling f

*

Out[8] = {Hold[Print["*"]], Symbol}

We see that the printing still takes place, and while the held part is ok,

the head part still computes the Head of the evaluated argument (that's

where the printing happens). This is because this time, Head needs

Unevaluated - we redefine <f>:

In[9] =

Clear[f];

f[x_] := {Hold[x],Head[Unevaluated[x]]};

In[10] =

Function[y, (Print["Just before calling f"]; f[Unevaluated[y]]),

HoldAll][Print["*"]]

Just before calling f

Out[10]= {Hold[Print[*]],Print}

Now we get what we want. Hopefully by this moment the pattern started to

emerge. Note that Unevaluated is unnecessary if the function itself holds

its argument, possessing one of the hold attributes:

In[11]=

ClearAll[f];

Attributes[f] = {HoldAll};

f[x_] := {Hold[x], Head[Unevaluated[x]]};

In[12] =

Function[y, (Print["Just before calling f"]; f[y]), HoldAll][Print["*"]]

Just before calling f

Out[12]= {Hold[Print[*]],Print}

It is slightly off the main line of the argument, but another common

pitfall associated with this sort of things is something like this:

In[13] = {Hold[#] &[5^2],Hold[5^2]}

Out[13] = {Hold[25],Hold[5^2]}

The #-& notation is so routinely used that one often forgets that it does

introduce an additional parameter-passing stage. This is what one should use

to avoid evaluation during that stage:

In[14] = {Function[Null, Hold[#], HoldAll][5^2], Hold[5^2]}

Out[14] = {Hold[5^2], Hold[5^2]}

Sometimes the opposite is needed however:

In[15]:=

i = 0;

Function[x, {x, x, x}, HoldAll][i++]

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

In[16] = i

Out[16] = 3

In[17]:=

i = 0;

Function[x, {x, x, x][i++]

Out[17]= {0, 0, 0}

In[18] = i

Out[18] = 1

In this case, chances are that the first behavior is not what was intended.

So, to summarize: Hold is mostly useful to prevent evaluation of some

results, in between some other evaluations. Unevaluated in useful to force

some function use - just once, in this particular evaluation (for its

r.h.s.) - its original (unevaluated) argument if that function does not

have a corresponding hold attribute. Hold attributes are useful for the same

thing, but 1) They are permanent, not just one-time use 2) Unevaluated

wrappers are stripped off when evaluator meets them "on the way up", so

subsequent evaluation uses already normal version of the argument - not so

with attributes 3) You may need to work with functions written by others (or

system functions), for which changing attributes even temporarily may have

undesired/unpredictable consequences - in this case Unevaluated is more

appropriate, to make up for the lacking hold attribute just once. Perhaps,

another way to put is is that attributes belong to the function, while

Unevaluated "belongs" to a particular argument (though affecting the

execution of the function on that argument as if that function had a hold

attribute).

This is probably a very long-winded way to explain these things, but I hope

it will still clarify some issues.

Best regards,

Leonid

On Sun, May 31, 2009 at 3:37 AM, dabr...@indiana.edu

<dabr...@indiana.edu>wrote:

> Thanks a lot to Leonid, Szabolcs, and Ken for their solutions. I

> liked Leonid's the best, being both much simpler and more general than

> mine.

>

> SetAttributes[ShowIt, HoldAll];

> ShowIt[code_] :=

> Module[{y},

> Print[ToString[Unevaluated[code]], " = ", y = code];

> y];

>

> My own solution was the hideous

>

> $PreRead=ReplaceAll[#,{{"dbgv","[",var_,"]"}:>{"Print","[",RowBox

> [{"\""<>var<>" = "<>"\"",",",var}],"]"}}]&;

>

> which makes dbgv work like a macro. The grotesqueness is because what

> $PreRead sees is a very raw input form, with expressions broken down

> into RowBox's. In a sense this is the most direct analog to Lisp's

> macros, but ... yechh.

>

Jun 3, 2009, 1:08:53 AM6/3/09

to

This is a *totally* *excellent* explanation! Thank you!

-- David

P.S. Now please write a description of the entire Mathematica REPL with the

same clarity and level of detail! Self-publish it on Amazon or Lulu - I'll

buy a copy and I bet most of the mathgroup list would too!

On Tue, Jun 2, 2009 at 3:42 AM, Leonid Shifrin <lsh...@gmail.com> wrote:

> Hi,

>

> Just to add some more to the reply of Szabolcs:

>

<... lots of GOOD STUFF omitted ...>

Jun 5, 2009, 4:06:08 PM6/5/09

to

Leonid,

This is a really good explanation of evaluation. I'm still struggling

to internalize this, even after using Mathematica for years. I'm

curious about one point you raised. In this example:

> In[7] = Function[y, (Print["Just before calling f"]; f[y]),

> HoldAll][Print["*"]]

>

> Just before calling f

>

> *

>

> Out[7]= {Hold[Null],Symbol}

the result is different than when leaving off the explicit HoldAll:

In[32]:= Function[y, (Print["Just before calling f"]; f[y])][

Print["*"]]

During evaluation of In[32]:= *

During evaluation of In[32]:= Just before calling f

Out[32]= f[Null]

Yet the documentation for Function says:

Function has attribute HoldAll. The function body is evaluated only

after the formal parameters have been replaced by arguments.

How is the explicit HoldAll attribute different from the inherent

HoldAll? Why doesn't Function normally act as with the explicit

HoldAll?

Thanks.

Jun 5, 2009, 4:08:12 PM6/5/09

to

Stonewall,

The Function command must obey the general rules of Mathematica evaluation.

When we indicate HoldAll as an explicit attribute, this tells Function how

to pass the arguments to its body - to evaluate them first or not. But the

HoldAll attribute implicit for Function is always there, and that just

assures that Function is at all able to do its work, such as variable

binding and name conflict resolution (Function is a lexical scoping

construct). Consider an example:

In[1] =

x = 10;

Function[x, x^2] /@ Range[5]

Out[1] = {1, 4, 9, 16, 25}

The <x> inside a function has nothing to do with a global <x>, exactly due

to the HoldAll attribute of Function: it allows Function to analyze its

arguments (I mean, the body - x and x^2 in this case) and do the name

collision resolution before using the arguments.

(there is a slight confusion in terminology here because Function is a

SubValues-based construct: Function[body][args], so when I mean arguments, I

mostly mean body :), because that's what is affected by the attributes of

Function). So, in a sense, the confusion arises because this is the case

when Function itself is a subject to the same logic.

Now, removing the HoldAll attribute from Function is equivalent to using

Evaluate on all its arguments:

In[2] = Function[Evaluate[x],Evaluate[x^2]]/@Range[5]

During evaluation of In[2]:= Function::flpar: Parameter specification 10 in

Function[10,100] should be a symbol or a list of symbols. >>

...

Out[2]=

{Function[10,100][1],Function[10,100][2],Function[10,100][3],Function[10,100][4],Function[10,100][5]}

The error messages are because the first argument of Function must be

variable name, or a list of variable names (for named variables), but <x>

now evaluates to its global value, and the action of Function[10,100] on any

argument is undefined and thus the expression is just returned (note by the

way that if we would know/be able to see the system (built-in) global

rules/definitions for Function, they would be SubValues, not DownValues). In

the following case:

In[3] =

Clear[y];

Function[Evaluate[y], Evaluate[x^2]] /@ Range[5]

Out[3] = {100, 100, 100, 100, 100}

It at least understands what to do since <y> has no global value and is a

symbol. In the latter case, formally the result would be the same if we make

a "normal" call:

In[4] = Function[y, x^2] /@ Range[5]

Out[4] = {100, 100, 100, 100, 100}

Tracing shows the difference in evaluation however:

In[5] = Function[Evaluate[y], Evaluate[x^2]][1] // Trace

Out[5] = {{{{x,10},10^2,100},Function[y,100]},Function[y,100][1],100}

In[6] = Function[y, x^2][1] // Trace

Out[6] = {Function[y,x^2][1],x^2,{x,10},10^2,100}

By the way, sometimes we may want to force the first (or both) of the

arguments of the Function (the variable name or list of names) to be

evaluated. This happens when we want to force Function perform the variable

binding with the exact variable names that we provide. One such case happens

when we have a list of variables (and possibly the rhs) separately:

In[7] =

Clear[x1,x2,x3]

vars = {x1,x2,x3};

expr = x1*x2*x3;

In[8] = {#, #[1, 2, 3]} &@Function[vars, expr]

Out[8] = {Function[vars, expr], x1 x2 x3}

In[9] = {#, #[1, 2, 3]} &@Function[Evaluate[vars], expr]

Out[9] = {Function[{x1, x2, x3}, expr], x1 x2 x3}

In[10] = {#, #[1, 2, 3]} &@Function[Evaluate[vars], Evaluate[expr]]

Out[10] = {Function[{x1, x2, x3}, x1 x2 x3], 6}

We see that in the latter case, we achieved the correct binding. I have to

add however that separating variables and body in such a manner can be error

prone and probably should be avoided in favor of safer techniques to achieve

the same goal. For example, if x1,x2,x3 would have global values, we are in

trouble:

In[11] =x1 = 1; x2 = 2; x3 = 3;

In[12]:= Function[Evaluate[vars],Evaluate[expr]]

During evaluation of In[100]:= Function::flpar: Parameter specification

{1,2,3} in Function[{1,2,3},6] should be a symbol or a list of symbols. >>

Out[12]= Function[{1,2,3},6]

One way to make this safer in this case is to wrap everything in Block:

In[13] =

x1 = 1; x2 = 2; x3 = 3;

Block[{x1, x2, x3}, {#, #[1, 2, 3]} &@

Function[Evaluate[vars], Evaluate[expr]]]

Out[13] = {Function[{x1, x2, x3}, x1 x2 x3], 6}

But this wouldn't save us if x1,x2,x3 would have global values at the moment

when we defined <expr> and <vars>. So it is best to avoid globals.

In[14] = Clear[x1,x2,x3];

Another class of situations where we may want to do this is when we want to

prevent variable renaming that normally happens during the name collision

resolution in nested scoping constructs. Here is a (rather contrived)

example from the top of my head:

In[15] = Module[{x}, Function[x, x^2]] // FullForm

Out[15] = Function[x,Power[x,2]]

In[16] = Module[{x}, Function[Evaluate[x], x^2]] // FullForm

Out[16] = Function[x$246,Power[x$246,2]]

We see that Function in the first case protects its variable which remains

just <x> (as a symbol name), while in the second it is given a name

generated by Module. When can this ever be useful? Well, if you use

introspection in your code (such as writing macros that analyze/transform

your code), then the second case can protect the code from what is called in

Lisp a "variable capture" - when several instances of <x> belonging to

different lexical scopes would mistakingly be considered by a macro to be

the same x, or similar problems.

Probably all these examples are appropriate to be categorized as advanced

techniques, so normally you don't want to play with Function in this manner.

But I think they clarify the role of internal (implicit) HoldAll that the

Function possesses.

To summarize: this internal HoldAll has nothing to do with the arguments

passed to the function Function[body][arguments]

(and, by the way, never could, because in expression f[x][y],

only the processing of <x> is affected by the attributes of <f>), but with

the <body> passed to the function <Function> itself, and is needed for the

correct operation of the Function itself. OTOH, correct processing of

<arguments> according to the attributes given explicitly in the <body> of

Function is a task of Function's implementation.

Hope this helps.

Regards,

Leonid

Jun 11, 2009, 9:45:14 PM6/11/09

to

> The Function command must obey the general rules of Mathematica evaluatio=

n.

> When we indicate HoldAll as an explicit attribute, this tells Function ho=

w

> to pass the arguments to its body - to evaluate them first or not. But th=

e

> HoldAll attribute implicit for Function is always there, and that just

> assures that Function is at all able to do its work, such as variable

> binding and name conflict resolution (Function is a lexical scoping

> construct). Consider an example:

>...

n.

> When we indicate HoldAll as an explicit attribute, this tells Function ho=

w

> to pass the arguments to its body - to evaluate them first or not. But th=

e

> HoldAll attribute implicit for Function is always there, and that just

> assures that Function is at all able to do its work, such as variable

> binding and name conflict resolution (Function is a lexical scoping

> construct). Consider an example:

The key here that I didn't understand before is that the implicit

HoldAll attribute of Function applies to the arguments of Function,

not the resultant function. It's probably wrong of me to think that

Function[args, body] creates an object which is then applied to args.

Very lispy thinking.

The attributes argument to Function is needed, then, because there's

no other way to set attributes for subvalues. This is just another

part of the complexity cascade in Mathematica. For example:

In[1]:= Clear[foo, bar]

In[2]:= b = 5

Out[2]= 5

In[3]:= SetAttributes[foo, HoldAll]

In[4]:= foo[b]

Out[4]= foo[b]

In[5]:= bar[b]

Out[5]= bar[5]

In[6]:= foo[b][b]

Out[6]= foo[b][5]

> ...

> To summarize: this internal HoldAll has nothing to do with the arguments

> passed to the function Function[body][arguments]

> (and, by the way, never could, because in expression f[x][y],

> only the processing of <x> is affected by the attributes of <f>), but wit=

h

> the <body> passed to the function <Function> itself, and is needed for th=

e

> correct operation of the Function itself. OTOH, correct processing of

> <arguments> according to the attributes given explicitly in the <body> of

> Function is a task of Function's implementation.

>

> Hope this helps.

Yes, indeed. Thanks.

- Stoney

Jun 16, 2009, 9:47:28 PM6/16/09

to

Hi Stoney,

The key here that I didn't understand before is that the implicit

> HoldAll attribute of Function applies to the arguments of Function,

> not the resultant function. It's probably wrong of me to think that

> Function[args, body] creates an object which is then applied to args.

> Very lispy thinking.

This is correct - Function[args,body] is just some symbolic expression

which Mathematica does not know what to do with, so it is kept unevaluated

(in the sense that there are no built-in DownValues defined for Function, or

at least so it appears)

>

>

> The attributes argument to Function is needed, then, because there's

> no other way to set attributes for subvalues.

This is not quite what I meant (if I understood your statement correctly).

Attributes are always set for a given symbol, rather than for a given global

rule, and affect only the evaluation of sub-expressions for which this

symbol is a head in a given expression. If you give a HoldAll attribute to a

symbol <f>, all we know is that in an expression f[x] <x> will be kept

unevaluated (unless <x> has a head Evaluate), but we don't know whether f[x]

will be used as an element of some other expression, like say f[x]+f[y]

(which is more common, and then it will be rewritten if f has a DownValues

definition matching unevaluated form of <x>), or as a composite head

f[x][el1,el2,...], in which case f should have a SubValues - based

definition for this to be rewritten into something else.

What I mean is that the attributes of <f> govern the treatment of <x> in

f[x], regardless of which of these two scenarios is realized. This is

because the evaluation of expressions like f[g][h][x,y] is recursive, with

all "higher" heads being completely evaluated before elements of the

corresponding expression start to be evaluated, so f[g] evaluates

completely, then f[g][h] evaluates completely, and then f[g][h][x,y]

evaluates (this is a different recursion from that involved just in

evaluation of general mathematica expressions, with the latter containing

the former as a part of each of its recursive steps - we may call it "head

recursion", and I agree that it adds to the complexity of Mathematica

evaluator. I think though that the possibilities it opens have not been

fully explored yet. In fact, I find it remarkable enough that you may in

principle use these possibilities to implement pure functions (Function

construct) themselves, from the more fundamental language constructs such as

rewrite rules. In a sense, this is the answer to the question: Function

itself is not a fundamental language feature, but something (that can be)

implemented on top of the core language, and the internal HoldAll attribute

is a part of that implementation).

Here is, for the sake of example, a possible implementation of the simplest

Function functionality (no attributes for arguments, no name conflict

resolution with other scoping constructs, no anonimous arguments (slots),

single argument syntax not supported, no diagnostic/error messages):

Clear[myFunction];

SetAttributes[myFunction, HoldAll];

myFunction[argnames_List, body_][arguments__] /;

Length[{arguments}] >= Length[Unevaluated[argnames]] :=

First[Hold[body] /.

First[RuleDelayed @@@

Thread[Hold[

Evaluate[HoldPattern /@ Hold @@ Unevaluated[argnames]],

Evaluate[

Take[Hold[arguments], Length[Unevaluated[argnames]]]]],

Hold] /. Hold[x__RuleDelayed] :> Hold[{x}]]]

This is perhaps too long and ugly, and can be done much better and shorter,

but it suffices to illustrate the point. For example:

In[1] = x=1;y=2;

In[2] = myFunction[{x, y}, x + y][a, b, c]

Out[2] = a+b

You may change HoldAll for myFunction to HoldFirst or HoldRest, or remove it

alltogether, and see what happens. Now, it is another implementation

question how to make myFunction hold arguments <arguments> when we use a

form myFunction[argnames,body,HoldAll][arguments] or other Hold attributes.

The internal HoldAll present in myFunction will not by itself do it.

So, coming back to the main discussion, should HoldAll attribute in Function

be absent, and <argument names>, <body> inside Function would evaluate so

that we have Function[<evaluated argument names>, <evaluated body>] even

before we supply any actual arguments. Premature evaluation of argument

names is bad since it will prevent the correct variable binding, while

premature evaluation of <body> is equally bad since the body is not meant to

be evaluated until variable binding is performed and actual arguments are

passed as Function[arg names,body][arguments]. So, you may say that the

internal HoldAll is needed since Function[arg names,body] is subject to the

general procedure of Mathematica evaluation, while we want to prevent the

evaluation of <arg names>, <body>. This has nothing to do with the actual

parameters being passed to the pure function at a later point, and governs

the steps happening "before" it in the evaluation procedure. Sorry if this

is also what you meant and I just restated the obvious.

Regards,

Leonid

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu