Re: Re: named pattern variable scoped as global, should be local
- To: mathgroup at smc.vnet.net
- Subject: [mg56857] Re: [mg56720] Re: [mg56696] named pattern variable scoped as global, should be local
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Sat, 7 May 2005 15:35:19 -0400 (EDT)
- References: <200505040433.AAA06165@smc.vnet.net> <200505051001.GAA21799@smc.vnet.net> <000a01c552ff$474046a0$84d19b83@pc5>
- Sender: owner-wri-mathgroup at wolfram.com
Fred, As usual very good and convincing analysis. As for whether this behaviour constitutes a "bug" or not: I think this is probably one of those cases that only the person who wrote the code can give the true answer. It seems to me reasonable to define a bug as something in the code that causes behaviour that is undesirable in a way that either not realised by the programmer or could not have been avoided without causing even more undesirable behaviour (this latter situation is quite common in programs like Mathematica). I am now also inclined to think that under the above definition this probably does not qualify as a bug. It seems to me that this behaviour is mildly undesirable and causes some difficulty to users, but probably it is a side effect of something intentional. Still, I do not see any obvious benefits form $ not being appended when the RHS contains unscoped variables; maybe this improves performance but the gain seems to be very slight. Perhaps the reason lies in trying to be consistent with some more general principles of scoping. Unfortunately these "principles" do not appear to be clearly stated anywhere, which of course is one reason why "detective work" like yours is so valuable (as well as entertaining). Andrzej On 7 May 2005, at 20:46, Fred Simons wrote: > > Andrzej, > > I agree that it is at least very surprising that the following two > commands > produce different results: > > In[1]:= > x=7; > Module[{x}, z /. x_->2 x] > Module[{x, y=1}, z /. x_->2 x y] > > Out[2]= > 14 > Out[3]= > 2 z > > Whether this has to be considered as a bug or not is a matter of taste. > After all, these commands are pretty artificial. > > In the following I try to give a possible explanation of what is going > on > here. I start with the observation that when in a scoping construct an > expression has to be evaluated that contains other variables than than > those > that will be scoped, a $-sign is appended to the scoped variables. A > number > is added only when the evaluation takes place. Have a look at the > following > example, with Module. > > In[4]:= > Clear[f]; f[t_] = Hold[ Module[{x}, x+t]]; > f[3] > ReleaseHold[%] > > Out[5]= > Hold[Module[{x$},x$+3]] > Out[6]= > 3+x$18 > > When the expression to be evaluated does not contain variables from > outside > the scoping construct, the precaution of appending a $-sign does not > take > place: > > In[7]:= > Clear[f]; f[t_] = Hold[ Module[{x}, x]]; > f[3] > ReleaseHold[%] > > Out[8]= > Hold[Module[{x},x]] > Out[9]= > x$19 > > It works exactly the same way with Rule instead of Module: > > In[10]:= > Clear[f]; > f[t_] := Hold[x_ -> 2*x + t] > f[3] > > Out[12]= > Hold[x$_ -> 2*x$ + 3] > > In[13]:= > Clear[f]; > f[t_] := Hold[x_ -> 2*x] > f[3] > Out[15]= > Hold[x_ -> 2*x] > > Now we turn to the two commands we started with. In > > Module[{x}, z /. x_->2 x], > > the expression that has to be evaluated within Rule only contains the > named > pattern. Therefore no $ sign is used; it is the variable Global`x. The > value > of that variable is not hidden by Module, so the right-hand side of > the rule > becomes 14: > > In[16]:= > Module[{x}, z /. x_ -> (Information[x]; 2*x)] > >> From In[16]:= > "Global`x" > From In[16]:= > x = 7 > Out[16]= > 14 > > By the way, when we use Block instead of Module, the value of Global`x > is > hidden by Block and therefore it works as expected: > > In[17]:= > Block[{x}, z /. x_ -> (Information[x]; 2*x)] > >> From In[17]:= > "Global`x" > Out[17]= > 2*z > > In the second command > > Module[{x, y=1}, z /. x_->2 x y], > > the expression to be evaluated in the rule contains an extra variable > y. So > x becomes Global`x$ and that variable has no value: > > In[18]:= > Module[{x, y = 1}, > z /. x_ -> (Information[x]; 2*x*y)] > >> From In[18]:= > "Global`x$" > From In[18]:= > Attributes[x$] = {Temporary} > Out[18]= > 2*z > > Hence personally I think this behaviour is not a bug. > > Regards, > > Fred Simons > Eindhoven University of Technology > > > ----- Original Message ----- From: "Andrzej Kozlowski" To: mathgroup at smc.vnet.net > <akoz at mimuw.edu.pl> > To: <mathgroup at smc.vnet.net> > Sent: Thursday, May 05, 2005 12:01 PM > Subject: [mg56857] [mg56720] Re: [mg56696] named pattern variable scoped as > global, > should be local > > >> >> On 4 May 2005, at 13:33, leenewman at gmail.com wrote: >> >>> When using a named pattern variable within a module, it should be >>> scoped locally within the pattern. However, this does not seem to >>> work >>> as advertised. For example, shouldn't the pattern variable x in the >>> statements below be local to the pattern? Does anyone know whether >>> this is a bug, or whether I am just missing something about the usage >>> of variables in patterns/condition constructs? >>> >>> (* this returns 14! *) >>> x = 7; >>> Module[{x},{1, 2, 3} /. x_ -> 2x]; >>> >>> (* this returns {2,4,6}, assuming q is not globally defined. *) >>> Remove[q]; >>> Module[{q},{1, 2, 3} /. q_ -> 2q]; >>> >>> >>> Lee >>> >> >> To me this indeed looks like a bug, but Mathematica's scoping is >> strange and it is sometimes hard to tell what is a bug and what is a >> part of the design. >> >> The reason why it looks to me like a bug is this: >> >> x=7; >> Module[{x,y=1},{1,2,3}/.x_->2 x y] >> >> {2,4,6} >> >> besides this "workaround" I can see two other choices: >> >> 1. Use RuleDelayed: >> >> x=7; >> Module[{x},{1,2,3}/.x_:>2x] >> {2,4,6} >> >> 2. Use Block instead of Module: >> >> Block[{x},{1,2,3}/.x_->2x] >> >> {2,4,6} >> >> >> Andrzej Kozlowski >> Chiba, Japan >> http://www.akikoz.net/andrzej/index.html >> http://www.mimuw.edu.pl/~akoz/ >> >
- References:
- named pattern variable scoped as global, should be local
- From: leenewman@gmail.com
- Re: named pattern variable scoped as global, should be local
- From: Andrzej Kozlowski <akoz@mimuw.edu.pl>
- named pattern variable scoped as global, should be local