Re: Set::setraw error

*To*: mathgroup at smc.vnet.net*Subject*: [mg90358] Re: Set::setraw error*From*: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>*Date*: Mon, 7 Jul 2008 05:06:39 -0400 (EDT)*Organization*: The Open University, Milton Keynes, UK*References*: <g4q9kl$e6o$1@smc.vnet.net>

Steven Siew wrote: > I have encountered this Set:setraw error for the code below. > > I'm stumped. Does anyone have any idea what went wrong? > > xgcd[a_,b_]:=Module[{xsign=1,ysign=1,x=1,y=0,r=0,s=1,c,q}, > If[a == 0 && b == 0,Return[{0,0,1}]]; > If[a == 0,Return[{Abs[b],0,b/Abs[b]}] ]; > If[b == 0,Return[{Abs[a],a/Abs[a],0}]]; > If[a<0,a=-a; xsign=-1]; > If[b<0,b=-b; ysign=-1]; > While[b\[NotEqual]0, > {c,q}={Mod[a,b],Quotient[a,b]}; > {a,b,r,s,x,y}={b,c,x-q*r,y-q*s,r,s} > ]; > Return[{a,x*xsign,y*ysign}] > ] > > xgcd[2, 3] > > \!\(\* > RowBox[{\(Set::"setraw"\), \(\(:\)\(\ \)\), "\<\"Cannot assign to > raw \ > object \\!\\(2\\). \\!\\(\\*ButtonBox[\\\"More\[Ellipsis]\\\", \ > ButtonStyle->\\\"RefGuideLinkText\\\", ButtonFrame->None, \ > ButtonData:>\\\"Set::setraw\\\"]\\)\"\>"}]\) Hi Steven, Contrary to many programming languages, say of the Algol family (C/C++,Java.c#, etc.), the names that appears on the LHS of the definition of a function in Mathematica are *not* the declaration of some local variables but are names given to some *patterns* [1, 2, 3]; patterns that are going to be replaced by their values *before* evaluating the RHS of the function. One can think of Mathematica as a rewriting engine that takes some transformation rules as input and rewrite the code of a function according to them, before evaluating/executing the desired function. (That is why Mathematica excels as doing *symbolic* manipulation and mathematics.) So, when you ask Mathematica to evaluate xgcd[2, 3], Mathematica checks whether the expression xgcd[2, 3] matches some rule in its global database of transformation rules, and find that, indeed, the given expression matches xgcd[_, _]. Since the first and second patterns are named 'a' and 'b', respectively, Mathematica takes the RHS (or body) of the corresponding expression and rewrite it as follows: Module[{xsign = 1, ysign = 1, x = 1, y = 0, r = 0, s = 1, c, q}, If[2 == 0 && 3 == 0, Return[{0, 0, 1}]]; If[2 == 0, Return[{Abs[3], 0, 3/Abs[3]}]]; If[3 == 0, Return[{Abs[2], 2/Abs[2], 0}]]; If[2 < 0, 2 = -2; xsign = -1]; If[3 < 0, 3 = -3; ysign = -1]; While[3 != 0, {c, q} = {Mod[2, 3], Quotient[2, 3]}; {2, 3, r, s, x, y} = {3, c, x - q*r, y - q*s, r, s}]; Return[{2, x*xsign, y*ysign}]] Having done that, Mathematica executes the freshly rewritten code, and of course, assignment such as 2 = -2, that is the attempt to change the value of a number, is illegal. That is the meaning of the error messages you get. To avoid this issue, just change the name of the patterns on the LHS and assign them to some local variables declared within the Module[] construct. The following code works as expected. In[1]:= xgcd[aval_, bval_] := Module[{a = aval, b = bval, xsign = 1, ysign = 1, x = 1, y = 0, r = 0, s = 1, c, q}, If[a == 0 && b == 0, Return[{0, 0, 1}]]; If[a == 0, Return[{Abs[b], 0, b/Abs[b]}]]; If[b == 0, Return[{Abs[a], a/Abs[a], 0}]]; If[a < 0, a = -a; xsign = -1]; If[b < 0, b = -b; ysign = -1]; While[b != 0, {c, q} = {Mod[a, b], Quotient[a, b]}; {a, b, r, s, x, y} = {b, c, x - q*r, y - q*s, r, s}]; Return[{a, x*xsign, y*ysign}]] xgcd[0, 0] xgcd[0, -2] xgcd[-2, 0] xgcd[-2, 3] xgcd[2, -3] xgcd[2, 3] Out[2]= {0, 0, 1} Out[3]= {2, 0, -1} Out[4]= {2, -1, 0} Out[5]= {1, 1, 1} Out[6]= {1, -1, -1} Out[7]= {1, -1, 1} Regards, - Jean-Marc [1] guide/Patterns [2] "Introduction to Patterns", tutorial/Introduction-Patterns, http://reference.wolfram.com/mathematica/tutorial/Introduction-Patterns.html [3] "Patterns", tutorial/PatternsOverview, http://reference.wolfram.com/mathematica/tutorial/PatternsOverview.html