MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

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
>
>



  • Prev by Date: Re: Evaluation question
  • Next by Date: Re: Re: What is the purpose of the Defer Command?
  • Previous by thread: Re: Evaluation question
  • Next by thread: Re: Evaluation question