Unevaluated subtleties

*To*: mathgroup at smc.vnet.net*Subject*: [mg92683] Unevaluated subtleties*From*: magma <maderri2 at gmail.com>*Date*: Fri, 10 Oct 2008 04:35:56 -0400 (EDT)

I was thinking at how to measure the Length of an expression in the form that is entered by the user. The way to do it is: Length[Unevaluated[expr]] For example Length[Unevaluated[2+5]] gives 2 which is what I wanted since 2+5 is really Plus[2,5], a function with 2 arguments. So far so good. Then I started to experiment a bit with Unevaluated and I soon discovered that it behaves curiously . To peek at the inner workings of Mathematica I always like to switch On[] and then try remembering to switch Off[] again very quickly, before doing something silly. So look at this: Type: On[] Unevaluated[2+5]//Length Off[] and you get (line numbering added for clarity) On::trace: On[] --> Null. >> Length::trace: Length[Unevaluated[2+5]] --> Length[2+5]. >> (* Line 1 *) Length::trace: Length[2+5] --> 2. >> (* Line 2 *) Out[269]= 2 Which is what we got before. Now let's see what happens if we split the oneliner expression Unevaluated[2+5]//Length in 2 parts. Normally this should have no consequences, but in this case... On[] Unevaluated[2+5] %//Length Off[] On::trace: On[] --> Null. >> Out[280]= Unevaluated[2+5] Out::trace: % --> Out[$Line-1]. >> $Line::trace: $Line --> 281. >> Plus::trace: $Line-1 --> 281-1. >> Plus::trace: 281-1 --> 280. >> Out::trace: Out[$Line-1] --> %280. >> Out::trace: %280 --> Unevaluated[2+5]. >> Length::trace: Length[%] --> Length[Unevaluated[2+5]]. >> Length::trace: Length[Unevaluated[2+5]] --> 1. >> (* Line 3 *) Out[281]= 1 It gives a different result! This is vaguely hinted at in the Unevaluated info page under Properties & Relations "Unevaluated works only where it appears; it is not propagated" This probably means that it is not wise to split things up when dealing with Unevaluated. Yet, how does Mathematica know? Compare line 1 with line 3 : both start with the same Length[Unevaluated[2+5]], yet the result is different! I find this a bit amazing. Obviously something is going on behind the scenes that is not revealed with a simple On[]. Look now at Line 2. Isn't that amazing? A simple looking Length[2+5] is evaluated as 2. It should be either 0, because Length[7] is 0 or it should be 1, if we imagine some invisible wrapper (HoldForm?, Unevaluated?) protecting 2+5. Length has no special attributes, yet 2+5 is taken as Plus[2,5] and its length evaluates to 2. However all of this is totally invisible. Just for comparison type In[283]:= On[] Length[2+5] Off[] On::trace: On[] --> Null. >> Plus::trace: 2+5 --> 7. >> Length::trace: Length[2+5] --> Length[7]. >> (* Line 4 *) Length::trace: Length[7] --> 0. >> Out[284]= 0 Compare line 2 above with Line 4 here, they start the same, yet they end up very differently. All this suggests to me that either Unevaluated has a very odd and unique non-standard evaluation or that it has some undocumented side effects at least at a local (ie. temporary) level. Any comments?

**Follow-Ups**:**Re: FindFit***From:*danl@wolfram.com

**FindFit***From:*Artur <grafix@csl.pl>