Re: Re: named pattern variable scoped as global, should be local
- To: mathgroup at smc.vnet.net
- Subject: [mg56855] Re: [mg56720] Re: [mg56696] named pattern variable scoped as global, should be local
- From: "Fred Simons" <f.h.simons at tue.nl>
- Date: Sat, 7 May 2005 15:35:17 -0400 (EDT)
- References: <200505040433.AAA06165@smc.vnet.net> <200505051001.GAA21799@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
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" <akoz at mimuw.edu.pl> To: mathgroup at smc.vnet.net Subject: [mg56855] [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