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