Re: Evaluation question
- To: mathgroup at smc.vnet.net
- Subject: [mg82197] Re: Evaluation question
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Sun, 14 Oct 2007 06:17:35 -0400 (EDT)
- References: <200710120656.CAA04613@smc.vnet.net> <fepuqv$hvl$1@smc.vnet.net> <47109042.2000302@gmail.com> <AF26334E-9827-4055-8FEF-501F79F783AE@mimuw.edu.pl>
On 14 Oct 2007, at 08:00, Andrzej Kozlowski wrote:
> Wihtout evaluation 1+2 is just a symbol and not the number 3 so
> NumericQ returns False.
I should have been more precise. Unevaluated 1+2 is an expression
(rather than a symbol); in fact it is the expression Plus[1,2], which
of course is not numeric. It's value is, of course, numeric, but that
is obtained only after evaluation.
Andrzej Kozlowski
>
> On 13 Oct 2007, at 18:30, Szabolcs Horv=E1t wrote:
>
>> Andrzej Kozlowski wrote:
>>> On 12 Oct 2007, at 15:56, Yaroslav Bulatov wrote:
>>>> At what point is "Unevaluated" stripped?
>>>>
>>>> For instance, in the following, unevaluated is stripped even though
>>>> arguments are not evaluated
>>>> a := Unevaluated[2 + 3]
>>>>
>>>> So a:=Unevaluated[2+3] and a=Unevaluated[2+3] seem to work the same
>>>> here
>>>>
>>> Unevaluated is stripped from an argument of a function before
>>> the function is checked for the Hold attributes. It is easy to
>>> see this with Trace:
>>> SetAttributes[f, HoldAll]
>>> Trace[f[Unevaluated[x]]]
>>> {HoldForm[f[x]], HoldForm[f[Unevaluated[x]]]}
>>> Unevaluated was stripped but then it was restored, as the
>>> expression did not change. On the other hand here Unevaluated is
>>> stripped but this time not restred:
>>> Trace[a := Unevaluated[2 + 3]]
>>> {HoldForm[a := 2 + 3], HoldForm[Null]}
>>> Normally, Unevaluated that had been stripped from an argument is
>>> restored if no applicable rules were found after it was stripped.
>>> In this case it is, however, not restored, and to tell the truth
>>> at the moment it is not clear to me why.
>>>> Also, consider
>>>>
>>>> a=Unevaluated[Unevaluated[2+3]]
>>>> OwnValues[a]
>>>>
>>>> OwnValues doesn't show that a has an Unevaluated wrapper, even
>>>> though
>>>> a /. OwnValues[a] results in Unevaluated[2+3], why is that?
>>> Doing a Trace on OwnValues clearly shows evaluation:
>>> Attributes[OwnValues]
>>> {HoldAll, Protected}
>>> a = Unevaluated[Unevaluated[2 + 3]]
>>> Trace[OwnValues[a]]
>>> {HoldForm[OwnValues[a]], HoldForm[{HoldPattern[a] :> Unevaluated
>>> [2 + 3]}],
>>> {HoldForm[HoldPattern[a] :> 2 + 3],
>>> HoldForm[HoldPattern[a] :> 2 + 3]},
>>> HoldForm[{HoldPattern[a] :> 2 + 3}]}
>>> You can clealry see that Unevaluated got stripped during
>>> evaluation of:
>>> HoldPattern[a] :> Unevaluated[2 + 3]
>>> HoldPattern[a] :> 2 + 3
>>> Just as in the earlier example Unevaluated is stripped but not
>>> restored, and again I find it a bit of a puzzle. Perhaps someone
>>> else can explain this point?
>>
>> It seems that Rule and RuleDelayed are "evaluated to themselves":
>>
>> In[1]:= Trace[1->2+3]
>> Out[1]= {{2+3,5},1->5,1->5}
>>
>> In[2]:= Attributes[f]=Attributes[Rule]
>> Out[2]= {Protected,SequenceHold}
>>
>> In[3]:= Trace[f[1,2+3]]
>> Out[3]= {{2+3,5},f[1,5]}
>>
>> Note the difference between the two completely analogous
>> situations. It seems that Rule is not just a symbol without
>> meaning, but it has some built-in definitions. (BTW, Rule and
>> RuleDelayed also influence scoping, and can interact in strange
>> ways with Module, Function etc.)
>
> It seems that you are right here. I have always thought that Rule
> was nothing more than a container but it seems indeed that it has
> some sort of rule attatched to it, which causes the doubl
> appearance of 1->5 in the above Trace and prevents Unevaluated from
> being restored. However, I am still puzzled by this. "Evaluates to
> itself" does not seem to me to explain much. It clearly is doing
> something which results in the same output as the input, at least
> in this case. But what?
>
>
>>
>> I did not know that Unevaluated is stripped and then *restored*
>> later. I thought that it works this way: Unevaluated is stripped
>> when the surrounding function is evaluated (more specifically:
>> when the DownValues are applied), but it is left untouched if no
>> DownValues apply. This seems to be consistent with the fact that
>> Rule is "evaluated to itself", and that Unevaluated is stripped
>> from Rule.
>
> The stripping of Unevaluated is described wherever the Mathematica
> main evaluation loop is described, which, as far as I know is in
> David Whithoff's article of 1993 (which used to be available on
> MathSource and perhaps still is), in David Wagner's book "Power
> Programming with Mathematica". I tis also described in Michael
> Trott's Mathematica Guide Books (the Programming section), though
> not in as much detail.
>
>
>>
>> After a little experimentation, I think I understand why
>> Unevaluated is stripped and restored. Consider the following
>> example:
>>
>> In[1]:= f[x_?StringQ] := x
>>
>> In[2]:= f[Unevaluated[1+2]]//Trace
>> Out[2]= {f[1+2],{{1+2,3},StringQ[3],False},f[1+2],f[Unevaluated[1
>> +2]]}
>>
>> However, there are still a few strange things that I do not
>> understand (apart from the behaviour of Rule). For example:
>>
>> In[1]:= NumericQ[Unevaluated[1+2]]//Trace
>> Out[1]= {NumericQ[1+2],False}
>>
>> In[2]:= SetAttributes[f,NumericFunction]
>>
>> In[3]:= NumericQ[f[1,2]]//Trace
>> Out[3]= {NumericQ[f[1,2]],True}
>>
>> In[4]:= NumericQ[Unevaluated[f[1,2]]]//Trace
>> Out[4]= {NumericQ[f[1,2]],False}
>>
>
>
> I do not find this surprising. Wihtout evaluation 1+2 is just a
> symbol and not the number 3 so NumericQ returns False.
>
> Andrzej Kozlowski
>
>
- References:
- Evaluation question
- From: Yaroslav Bulatov <yaroslavvb@gmail.com>
- Evaluation question