Re: Evaluate/Module[Correction]
- To: mathgroup at smc.vnet.net
- Subject: [mg16133] Re: Evaluate/Module[Correction]
- From: "Allan Hayes" <hay at haystack.demon.co.uk>
- Date: Sat, 27 Feb 1999 03:23:05 -0500
- References: <7atq9s$7kr@smc.vnet.net> <7b32nl$1ss@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Paul Abbott, in an email that will be appearing as a posting, writes > I'm not convinced by your explanation. and gives the examples reproduced below the line **************************************** Yes: thanks Paul The account that I gave of the evaluation of CompoundExpression[...] is incorrect (I correct it below); but I think that the rest of the explanation is OK. Normally, CompoundExpression evaluates its entries in sequence and then gives the value of the last one. However, since it has the attribute HoldAll this evaluation is under the control of the programmer and if some entries are wrapped in Evaluate[ ] they will be evaluated first in order, and then the other entries will be evaluated in order. The last entry in the resulting expression is returned as the value of the compound expression, So, writing ei* for the value of ei, we get the following steps CompoundExpression[e1, Evaluate[e2], Evaluate[e3], e4] CompoundExpression[e1, e2*, Evaluate[e3], e4] CompoundExpression[e1, e2*, e3*, e4] CompoundExpression[e1*, e2*, e3*, e4] CompoundExpression[e1*, e2*, e3*, e4*] e4* I tripped up because of a misinterpretation of the following example: In[7]:= pr =. In[8]:= CompoundExpression[ {pr = Print, pr[2]}, Evaluate[{Print[1], pr[3]}] ] 1 2 3 Out[8]= {Null, Null} The printout shows the order of evaluation; and the 3 lead me to believe that the second entry had been evaluated a second time inside CompoundExpression[ ..]; and so to think that all entries wrapped in Evaluate were so re-evaluated. However, the following shows that this is not so, because no 3 is printed. What in fact had happened was that {Print[1], pr[3]} is returned by CompoundExpression and is then evaluated. In[62]:= pr =. CompoundExpression[ {pr = Print, pr[2]}, Evaluate[{Print[1], pr[3]}, 4 ] 1 2 4 Other points: >Incidentally, in your code > >tmp = x^2 +1; > >Module[{x=4}, tmp=tmp-1;Print[tmp]; Evaluate[tmp]] > >Module has no effect: >- the x are renamed x$n (where n is the ModuleNumber); but this is done >before the body > tmp=tmp-1;Print[tmp]; Evaluate[tmp] >is evaluated, so, only the displayed x is renamed. >- then the assigment x$n = 4 is made. >- after this the body evaluates to x^2+1 but this involves x, not x$n, so >the assignment has no effect. And taking up my suggestion to Evaluate the body we get In[1]:= tmp = x^2 +1; In[2]:= Module[{x=4}, Evaluate[tmp=tmp-1;Print[tmp]; Evaluate[tmp]]] x^2 Out[2]= 17 Because, overiding the HoldAll attribute of Module, first the body evaluates to x^2 +1 ( printing x^2 on the way) giving Module[{x=4}, x^2+1] Then we get the local varable form Module[{x$n=4}, x$n^2+1] The assignment x$n=4 is then made and x$n^2+1] therefore evaluates to 4^2+1, that is 17. A variant of this is: In[3]:= tmp = x^2 +1; In[4]:= Module[{x=4}, Evaluate[tmp=tmp-1;Print[tmp]; tmp]] x^2 Out[4]= 16 And, also , with yet another outcome, In[5]{= tmp = x^2 +1; In[6]:= x=4; tmp=tmp-1;Print[tmp]; Evaluate[tmp] 16 Out[6]= 17 The following is an account of the evaluation of Paul's inputs, using these ideas. I abbreviate CompoundExpression to CE In[7]:= a = 1; a = a - 1; Evaluate[a] Out[7]= 0 Evaluation steps CE[a = 1, a = a - 1, a] CE[1, a = a - 1, a] with a =1 stored CE[1, a = 1- 1, a ] ,, CE[1, a = 0, a ] ,, CE[1, 0, a ] with a=0 stored a ,, 0 Note: the final evaluation of a to 0 above is outside CE[..] - because the last entry had already been evaluated to a inside CE[...] Without Evaluate: In[8]:= a = 1; a = a - 1; a Out[8]= 0 Evaluation steps CE[a = 1, a = a - 1, a] CE[1, a = a - 1, a] a = 1 stored CE[1, a = 1- 1, a ] ,, CE[1, a = 0, a ] ,, CE[1, 0, a ] a = 0 stored CE[1,0,0] ,, 0 In[9]:= Module[{a = 1}, a = a - 1; Evaluate[a]] Out[9]= 1 Evaluation steps Module[{a$n = 1}, a$n = a$n - 1; Evaluate[a$n]] CE[ a$n = a$n - 1, Evaluate[a$n]], a$n = 1 stored CE[a$n =a$n - 1,1] ,, CE[a$n =1 - 1,1] ,, CE[a$n =0, 1 ] ,, CE[0,1] a$n = 0 stored In[10]:= Module[{a = 1}, a = a - 1; a] Out[10]= 0 Evaluation steps Module[{a$n = 1}, a$n = a$n - 1; a$n] CE[a$n = a$n - 1, a$n] a$n = 1 stored CE[a$n = 1 - 1, a$n] ,, CE[a$n = 0, a$n ] ,, CE[ 0, a$n ] a$n = 0 stored CE[0, 0 ] ,, 0 --------------------- Allan Hayes Mathematica Training and Consulting Leicester UK www.haystack.demon.co.uk hay at haystack.demon.co.uk Voice: +44 (0)116 271 4198 Fax: +44 (0)870 164 0565 **************************************************************************** ************ Allan Hayes wrote: > Neither problem invoves Module; both are due to how expressions like > e1;e2;e3;e4 (FullForm CompoundExpression[e1,e2, e3,e4] > evaluate > > Normally, CompoundExpression evaluates its entries in sequence and then > gives the value of the last one. However, since it has the attribute HoldAll > this evaluation is under the control of the programmer and if some entries > are wrapped in Evaluate[ ] they will be evaluated first *and* the the > resulting expression will then be evaluated as usual > So, writing ei* for the value of ei, we get the following steps > > CompoundExpression[e1, Evaluate[e2], Evaluate[e3], e4] > CompoundExpression[e1, e2*, Evaluate[e3], e4] > CompoundExpression[e1, e2*, e3*, e4] (*restart!*) > CompoundExpression[e1*, e2*, e3*, e4] > CompoundExpression[e1*, e2**, e3*, e4] > CompoundExpression[e1*, e2**, e3**, e4] > CompoundExpression[e1*, e2**, e3**, e4*] > e4* I'm not convinced by your explanation. Consider the following CompoundExpressions: In[1]:= a = 1; a = a - 1; Evaluate[a] Out[1]= 0 In[2]:= a = 1; a = a - 1; a Out[2]= 0 Now, compare these results with a simple Module: In[3]:= Module[{a = 1}, a = a - 1; Evaluate[a]] Out[3]= 1 In[4]:= Module[{a = 1}, a = a - 1; a] Out[4]= 0 Note that both Module and CompoundExpression have the HoldAll Attribute: In[5]:= Attributes[Module] Out[5]= {HoldAll, Protected} In[6]:= Attributes[CompoundExpression] Out[6]= {HoldAll, Protected, ReadProtected} Using Trace does give some idea as to what is going on: In[7]:= Trace[a = 1; a = a - 1; Evaluate[a]] Out[7]= {{a, 0}, a = 1; a = a - 1; 0, {a = 1, 1}, {{{a, 1}, 1 - 1, 0}, a = 0, 0}, 0} In[8]:= Trace[a = 1; a = a - 1; a] Out[8]= {a = 1; a = a - 1; a, {a = 1, 1}, {{{a, 1}, 1 - 1, 0}, a = 0, 0}, {a, 0}, 0} In[9]:= Trace[Module[{a = 1}, a = a - 1; a]] Out[9]= {Module[{a = 1}, a = a - 1; a], {a$9 = 1, 1}, {a$9 = a$9 - 1; a$9, {{{a$9, 1}, 1 - 1, 0}, a$9 = 0, 0}, {a$9, 0}, 0}, 0} In[10]:= Trace[Module[{a = 1}, a = a - 1; Evaluate[a]]] Out[10]= {Module[{a = 1}, a = a - 1; Evaluate[a]], {a$10 = 1, 1}, {{a$10, 1}, a$10 = a$10 - 1; 1, {{{a$10, 1}, 1 - 1, 0}, a$10 = 0, 0}, 1}, 1} Cheers, Paul ____________________________________________________________________ Paul Abbott Phone: +61-8-9380-2734 Department of Physics Fax: +61-8-9380-1014 The University of Western Australia Nedlands WA 6907 mailto:paul at physics.uwa.edu.au AUSTRALIA http://www.physics.uwa.edu.au/~paul God IS a weakly left-handed dice player ____________________________________________________________________