       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:=
x=7;
Module[{x}, z /. x_->2 x]
Module[{x, y=1}, z /. x_->2 x y]

Out=
14
Out=
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:=
Clear[f]; f[t_] = Hold[ Module[{x}, x+t]];
f
ReleaseHold[%]

Out=
Hold[Module[{x\$},x\$+3]]
Out=
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:=
Clear[f]; f[t_] = Hold[ Module[{x}, x]];
f
ReleaseHold[%]

Out=
Hold[Module[{x},x]]
Out=
x\$19

It works exactly the same way with Rule instead of Module:

In:=
Clear[f];
f[t_] := Hold[x_ -> 2*x + t]
f

Out=
Hold[x\$_ -> 2*x\$ + 3]

In:=
Clear[f];
f[t_] := Hold[x_ -> 2*x]
f
Out=
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:=
Module[{x}, z /. x_ -> (Information[x]; 2*x)]

From In:=
"Global`x"
From In:=
x = 7
Out=
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:=
Block[{x}, z /. x_ -> (Information[x]; 2*x)]

From In:=
"Global`x"
Out=
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:=
Module[{x, y = 1},
z /. x_ -> (Information[x]; 2*x*y)]

From In:=
"Global`x\$"
From In:=
Attributes[x\$] = {Temporary}
Out=
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