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


  • Prev by Date: Re: Mathematica Notebook Organiztion
  • Next by Date: Re: How to quickly find number of non-zero elements in sparse matrix rows?
  • Previous by thread: Re: named pattern variable scoped as global, should be local
  • Next by thread: Re: Re: named pattern variable scoped as global, should be local