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