Mathematica 9 is now available
Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2005
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

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/
>>
>


  • Prev by Date: Re: how call a function by same name in 2 different contexts?
  • Next by Date: Calling a MS-DOS command
  • Previous by thread: Re: Re: named pattern variable scoped as global, should be local
  • Next by thread: Re: Re: named pattern variable scoped as global, should be local