Re: rhs of SetDelayed

*To*: mathgroup at christensen.cybernetics.net*Subject*: [mg1592] Re: rhs of SetDelayed*From*: villegas (Robert Villegas)*Date*: Mon, 3 Jul 1995 03:16:03 -0400*Organization*: Wolfram Research, Inc.

> I have to define a few functions that take the same arguments. > Therefore I don't want to write the list of agguments repeatedly > and use a variable instead. > The following approach: > > lhsArg={a1_,a2_,a3_,a4_}; > rhrArg={a1,a2,a3,a4}; > f[lhsArg]:=g[rhsArg]; > > does not work. The left side is o.k. but since rhsArg is not > converted to {a1,a2,a3,a4} the right side is not. > How does one do this ? Michael, The right side stayed unevaluated because you used the := assignment (SetDelayed). If you use the = assignment (Set), then 'rhsArg' will be evaluated. In[1]:= lhsArg={a1_,a2_,a3_,a4_}; In[2]:= rhsArg={a1,a2,a3,a4}; In[3]:= f[lhsArg] = g[rhsArg] Out[3]= g[{a1, a2, a3, a4}] In[4]:= ? f Global`f f[{a1_, a2_, a3_, a4_}] = g[{a1, a2, a3, a4}] Note well that a1, a2, a3, a4 on the right side will evaluate, so you want to make sure they don't have values at this point in your session. If you believe they might, then you can enclose the whole assignment in a Block: In[5]:= {a1, a2, a3, a4} = {1, 2, 3, 4}; In[6]:= Clear[f] In[7]:= Block[{a1, a2, a3, a4}, f[lhsArg] = g[rhsArg]; ] In[8]:= ? f Global`f f[{a1_, a2_, a3_, a4_}] = g[{a1, a2, a3, a4}] This keeps out the global values of the ai while the assignment is being made. Without the Block, the right side would become g[{1, 2, 3, 4}], which probably isn't what you want. This method does still let the function g evaluate at the symbols a1, a2, a3, a4 and occasionally you might want to prevent even that: the function might be one that should wait until it receives numerical arguments, and cannot sensibly operate on symbols. Most of the time you don't have to worry about it, but in case you do, a simple cure is to include g in the Block: (* Define g to announce its evaluation so we can be sure our methods don't evaluate it: *) In[9]:= g[expr_] := Print[expr^2] In[10]:= Clear[f] In[11]:= Block[{a1, a2, a3, a4, g}, f[lhsArg] = g[rhsArg]; ] In[12]:= ? f Global`f f[{a1_, a2_, a3_, a4_}] = g[{a1, a2, a3, a4}] Or you can construct your original := (SetDelayed) assignment by inserting the value for rhsArg into the template you gave: f[lhsArg] := g[rhsArg] There are a lot of ways to do this type of thing. Here's one: In[13]:= Clear[f] In[14]:= Unevaluated[f[lhsArg] := g[rhsArg]] /. OwnValues[rhsArg] In[15]:= ? f Global`f f[{a1_, a2_, a3_, a4_}] := g[{a1, a2, a3, a4}] Unevaluated keeps the := assignment frozen during the /. substitution. OwnValues[rhsArg] is a held rule expressing the stored value of 'rhsArg'. You use it like any other x -> 1 rule, but it keeps both left and right sides unevaluated during the substitution. In[16]:= OwnValues[rhsArg] Out[16]= {HoldPattern[rhsArg] :> {a1, a2, a3, a4}} Robby Villegas