Re: Evaluation question
- To: mathgroup at smc.vnet.net
- Subject: [mg82205] Re: Evaluation question
- From: Szabolcs Horvát <szhorvat at gmail.com>
- Date: Sun, 14 Oct 2007 06:21:42 -0400 (EDT)
- References: <200710120656.CAA04613@smc.vnet.net> <fepuqv$hvl$1@smc.vnet.net>
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.) 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. 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} -- Szabolcs
- References:
- Evaluation question
- From: Yaroslav Bulatov <yaroslavvb@gmail.com>
- Evaluation question