Fred,
At several points you made statements I simply don't understand. The examples clarify what you meant for the most part, but I'm still wondering, so here goes:
>> Unevaluated is meant to pass unevaluated arguments to a function
>> body and as such it works perfectly. No one in practice is interested
>> in (1+1)*Unevaluated[2+2].
Do you mean a Function body? If not, Times in that example qualifies as a function body. (I think.)
>> If now no rules for f can be applied, Mathematica returns the result
>> so far, with Unevaluated wrapped again around the labeled arguments.
So it's only rules FOR F that matter? Does the distributive property count as a rule for Times?
>> If a rule for f can be applied, the administration of arguments
>> that come from Unevaluated is completely skipped.
I don't get any meaning from the phrase "administration of arguments".
>> I first formulate my assumption (only WRI and maybe a few others
>> know if I am right!)
Even if your assumption is correct (as I suspect it is), this statement doesn't really square with a later claim that there's no mystery.
>> But when I ask for this result without copying and pasting
>> it does NOT evaluate to 2 (1+Sqrt[3])^2.
How do you "ask for this result without copying and pasting"?
Maybe you meant writing Sqrt[2]*Unevaluated[Sqrt[3] + 1]*(1 + Sqrt[3])*Unevaluated[Sqrt[2]] in an input cell (manually) and evaluating. When I enter it in InputForm like that, it doesn't evaluate to 2 (1+Sqrt[3])^2. But when I enter it in the more visual form, with radicals, it DOES evaluate. THIS IS VERY STRANGE.
But is that what you meant?
Bobby
On Fri, 24 Dec 2004 05:58:58 -0500 (EST), Fred Simons <f.h.simons at tue.nl> wrote:
>
>
> So far I could resist the temptation to participate in this discussion.
> However, in his mail Maxim Rytin presents some examples of which he thinks
> the result is unpredictable.
>
> Maybe there is some interest in how I predict the results of simple commands
> in which Unevaluated occurs. Of course these examples are of no practical
> interest. Unevaluated is meant to pass unevaluated arguments to a function
> body and as such it works perfectly. No one in practice is interested in
> (1+1)*Unevaluated[2+2].
>
> The basic principle has been clearly explained by Andrzej Kozlowsky. Suppose
> we have a function f that we call with one or more Unevaluated arguments.
> The first step in the evaluation procedure is that arguments are evaluated
> as far as allowed and attributes such as Orderless and Flat are applied. In
> this step Unevaluated is unwrapped from the argument, but Mathematica has
> labeled the arguments which come from Unevaluated. If now no rules for f can
> be applied, Mathematica returns the result so far, with Unevaluated wrapped
> again around the labeled arguments. If a rule for f can be applied, the
> administration of arguments that come from Unevaluated is completely
> skipped.
>
> Here are three illustrative examples. Try to predict the result!
>
> In[1] :=
> ClearAll[f]
> Attributes[f]={Orderless};
>
> f[b, Unevaluated[a]] // Trace
>
> Out[3]=
> {f[b,a],f[a,b],f[Unevaluated[a],b]}
>
> In[4]:=
> ClearAll[f]
> Attributes[f]={Orderless};
> f[x__]:= {x}[[1]];
> f[b, Unevaluated[a]] // Trace
>
> Out[7]=
> {f[b,a],f[a,b],{a,b}[[1]],a}
>
> In[8]:=
> ClearAll[f]
> Attributes[f]={Orderless, Flat};
> f[b, Unevaluated[f[a,c]]] // Trace
>
> Out[10]=
> {f[b,f[a,c]],f[b,a,c],f[a,b,c],f[Unevaluated[a],b,Unevaluated[c]]}
>
> The second example equals the first example, but now a rule for f is applied
> so the result is a instead of Unevaluated[a]. The third example demonstrates
> the labeling: the arguments a and c come from an Unevaluated argument in the
> function call. Since no rule for f is applied, they are wrapped with
> Unevaluated in the result, which is rather different from the original
> command.
>
> With respect to the functions Plus and Times the results seem to different.
> When we consider e.g. Times[Unevaluated[z], 2], we expect that in the first
> step of the evaluation due to the attribute Orderless of Times we arrive at
> Times[2, z] with z labeled as coming from an Unevaluated argument. Since no
> rules for Times can be applied, we expect the result to be 2*Unevaluated[z].
> But the result is 2*z.
>
> In order to understand what is going on here, we must have a closer look at
> the functions Plus and Times. I first formulate my assumption (only WRI and
> maybe a few others know if I am right!) and then I will explain and
> demonstrate it by some examples. Finally, using this hypothesis I will
> explain Maxim's counterexamples.
>
> Hypothesis: When Mathematica has to evaluate an expression with head Plus or
> Times, then immediately after the evaluation of the head, so before the use
> of the attributes, Mathematica calls a function that adds or multiplies all
> numerical arguments. If there are no other arguments, this result is the
> outcome of the evaluation. Otherwise Plus or Times is called with this
> numerical result as first argument followed by the remaining arguments.
>
> To illustrate the hypothesis we slightly modify the function Plus (the same
> can be done with Times) so that Mathematica tells us when and how Plus is
> called during the evaluation. Moreover, and that can be dangerous, we remove
> the attribute Orderless of Plus.
>
> In[13]:=
> Unprotect[Plus];
> Attributes[Plus]= Complement[Attributes[Plus], {Orderless}];
> Plus[x___] /; (Print["Plus"[x]];False) := 12
>
> In[16]:=
> 3 + c - 5 + b - a + 6
>
>> From In[16]:=
> Plus[4,c,b,-a]
>
> Out[16]=
> 4+c+b-a
>
> In[17]:=
> 2-5+10
>
> Out[17]=
> 7
>
> In the first example we see from the printed message that the first time
> Plus is called all numerical arguments are already added, the remaining
> arguments are not sorted. In the second example we see that Plus is not
> called at all.
>
> That indeed Mathematica automatically calls another function when an
> expression with head Plus or Times is met can be seen from the following
> example, for which we start with a fresh kernel.
>
> In[18]:=
> Quit[]
>
> In[1]:=
> Block[{Plus},
> Plus[a__]:= {a}[[1]];
> {Plus[x,1], Plus[1+12], Plus[12,x,-12]}]
>
> Out[1]=
> {1,13,x}
>
> Despite the fact that within the block we have a local variable Plus with a
> very different definition of the outside function Plus, the pre-evaluation
> mentioned in the hypothesis takes place! (I do not consider this as a bug in
> scoping but as a feature of the system names Plus and Times).
>
> So let us accept the hypothesis, let PrePlus and PreTimes be our names for
> the functions mentioned in the hypothesis and let us consider some example's
> of the type of Maxim's counterexamples.
>
> 1. Times[Unevaluated[z], 2]. PreTimes[Unevaluated[z], 2] applies a rule for
> PreTimes, so the labeling of arguments from Unevaluated disappears and we
> arrive at Times[2, z] with z not wrapped by Unevaluated.
>
> 2. 1 + 1 + Unevaluated[z]. PrePlus[1,1,Unevaluated[z]] applies a rule to
> arrive at Plus[2, z], so z is not wrapped with Unevaluated.
>
> 3. 2 + Unevaluated[z]. PrePlus[2, Unevaluated[z]] has no rules to apply so
> we arrive at Plus[2, z] with z still marked as coming from an Unevaluated
> argument, so the result is Plus[2, Unevaluated[z]] (a different result from
> the previous example!)
>
> 4. Unevaluated[2]/Sqrt[2]. PreTimes does not apply a rule, so we arrive at
> Times[2, 1/Sqrt[2]] with the first argument still marked. Now Times applies
> a rule and the result has no Unevaluated arguments.
>
> 5. Unevaluated[Sqrt[2] + Sqrt[2]]/Sqrt[2]. PreTimes does not apply a rule,
> so we arrive at Times[1/Sqrt[2], Sqrt[2]+Sqrt[2]] with the second argument
> labeled. Times has no rules for these arguments, so the outcome is
> Unevaluated[Sqrt[2] + Sqrt[2]]/Sqrt[2].
>
> 6. Unevaluated[Sqrt[2]*(Sqrt[3] + 1)]*Csc[Pi/12]. PreTimes does not apply a
> rule so due to the attribute Flat of Times we arrive at Times[Sqrt[2],
> Sqrt[3] + 1, 1 + Sqrt[3], Sqrt[2]], where the first two arguments are
> labeled. Mathematica 5.1 now returns Sqrt[2] Unevaluated[Sqrt[3] + 1] (1 +
> Sqrt[3]) Unevaluated[Sqrt[2]].
>
> That is correct, but it puzzles me. When I copy and paste this result in an
> Input cell and evaluate, the result now becomes 2 (1 + Sqrt[3])^2 . That is
> what I had expected and which is Maxim's result. But when I ask for this
> result without copying and pasting it does NOT evaluate to 2 (1+Sqrt[3])^2.
> This is more an evaluation problem (bug?) in version 5.1 than that is has to
> do with the basic properties of Unevaluated as discussed above.
>
> 7. Unevaluated[Sqrt[6]+Sqrt[2]]*Csc[Pi/12]. PreTimes does not apply a rule
> so we arrive at Times[Sqrt[2], 1 + Sqrt[3], Sqrt[6] + Sqrt[2]] with the last
> argument labeled. There are no rules for Times to be used, so Mathematica
> returns Sqrt[2]*(1 + Sqrt[3]) Unevaluated[Sqrt[6] + Sqrt[2]].
>
> Hence, despite the problem mentioned in example 6, my feeling is that there
> is nothing mysterious and unpredictable in the behaviour of Unevaluated in
> the examples discussed so far.
>
> Fred Simons
>
> Eindhoven University of Technology
>
>
>
>
>
--
DrBob at bigfoot.com
www.eclecticdreams.net