Re: set versus set-delay

*To*: mathgroup at smc.vnet.net*Subject*: [mg75243] Re: set versus set-delay*From*: Bill Rowe <readnewsciv at sbcglobal.net>*Date*: Sat, 21 Apr 2007 23:15:55 -0400 (EDT)

On 4/20/07 at 12:43 AM, siewsk at bp.com wrote: >SET versus SETDELAY >Newbie are always told to use SETDELAY instead of SET when they >create a mathematica function. This is generally good advice for someone starting out with Mathematica since functions defined using SetDelayed (not SETDELAY) will operate closer to what most people expect. >The objective of this article is to explain the differnce between >SET and SETDELAY using ordinary language (what linguistics call >vernacular language) >The main differences between those two are: >SET means CALCULATE FIRST THEN CHANGE >SETDELAY means CHANGE FIRST THEN CALCULATE >To explain, consider the following two functions f ang g >f[x_] = Expand[(x+7)^2] (* Using SET *) g[x_]:= >Expand[(x+7)^2] (* Using SETDELAY *) >The two functions are identical except f uses SET while g uses >SETDELAY. In normal usage there is no difference in the two >functions. However they produce their results using different steps. The explanation that followed (and I have snipped) is close to the mark but not quite there. The key difference is when the rhs of the expression gets evaluated. This is readily shown using Trace. =46irst with your f as above In[1]:= (f[x_]=Expand[(x+7)^2])//Trace Out[1]= {{{{HoldForm[x + 7], HoldForm[x + 7]}, HoldForm[(x + 7)^2]}, HoldForm[Expand[(x + 7)^2]], HoldForm[x^2 + 14*x + 49]}, HoldForm[f[x_] = x^2 + 14*x + 49], HoldForm[x^2 + 14*x + 49]} That is the result Expand[(x+7)^2] is evaluated and the result assigned to f. Using your terminology above, there is a calculation and a change. f has been changed. Then some time later In[2]:= f[4]//Trace Out[2]= {HoldForm[f[4]], HoldForm[49 + 14*4 + 4^2], {HoldForm[14*4], HoldForm[56]}, {HoldForm[4^2], HoldForm[16]}, HoldForm[49 + 56 + 16], HoldForm[121]} All parts of the expression that had x are immediately replaced with 4, then the resulting expression is evaluated Contrast this with In[3]:= (g[x_]:=Expand[(x+7)^2])//Trace Out[3]= {HoldForm[g[x_] := Expand[(x + 7)^2]], HoldForm[Null]} No evaluation of the expression has occurred Then later In[4]:= g[4]//Trace Out[4]= {HoldForm[g[4]], HoldForm[Expand[(4 + 7)^2]], {{HoldForm[4 + 7], HoldForm[11]}, HoldForm[11^2], HoldForm[121]}, HoldForm[Expand[121]], HoldForm[121]} The problem beginners usually have with using Set instead of SetDelayed is illustrated by In[17]:= Clear[f,x]; x=14; f[x_]=Expand[(x+7)^2]; f[4] Out[20]= 441 Since x had a defined value when f was defined Expand[(x+7)^2] evaluated to 441 and that was assigned to f. So, f now returns the constant 441 for all arguments, something a beginner definitely doesn't expect. Contrast this with In[21]:= Clear[g,x]; x=14; g[x_]:=Expand[(x+7)^2]; g[4] Out[24]= 121 which returns the desired value even though x was previously defined. The time to use Set is when you are the function is defined in terms of something Mathematica requires significant CPU time to compute and the result is used in a loop. Clearly, if the rhs includes say a complex integral, you don't want to solve the integral repeatedly as would occur with SetDelayed. But it is important to understand what is being evaluated and when. The particular function you chose illustrates using Set instead of SetDelayed will not always speed up evaluation. In this particular example, expansion of (x+7)^2 results in an expression that requires doing one multiply, one exponentiation and one addition to get the result. Leaving (x+7)^2 unevaluated until x is defined eliminates the multiply, i.e., SetDelayed results in fewer operations to get the same result. -- To reply via email subtract one hundred and four