Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[mg18132] Scoping and named patterns

0 views
Skip to first unread message

Ersek, Ted R

unread,
Jun 19, 1999, 3:00:00 AM6/19/99
to
Dr Dan (drd...@my-deja.com)
wrote about scoping and named patterns.
(see below)

-------------------------------------
Every few months this subject comes up in
the group.

As "Dr Dan" noticed Block can be used to
solve the problem.

Most of the time I avoid the problem by using
(:>) instead of (->). Also (->) isn't
the only feature with this problem.

Consider the following:
use of Rule: lhs->rhs
use of Set: lhs=rhs
use of UpSet: lhs^=rhs
use of TagSet f/:lhs=rhs
For each of the above whenever you have a named
pattern (e.g. x_) in (lhs) and the variable used
to name the pattern has a global value you will have
trouble. The global value of the variable will be used
in (rhs) but you want to use the value in (lhs) that
matches the pattern.


Instead you can do the following whenever practical.
If you need to use a named pattern in (lhs)
use (lhs):>(rhs) instead of (lhs)->(rhs)
use (lhs):=(rhs) instead of (lhs)=(rhs)
use (lhs)^:=(rhs) instead of (lhs)^=(rhs)
use f/:(lhs):=(rhs) instead of f/:(lhs)=(rhs)

----------------
Examples:

Using (lhs):>(rhs) instead of (lhs)->(rhs)
"Dr Dan's" example comes out right.

In[3]:=
n = 2; x = 3;
f[a^b] /. f[x : _^n_] :> p[x, n]

Out[3]=
p[a^b, b]

----------------
Here (x=3) from the line above
so (lhs)=(rhs) doesn't work right.

In[4]:=
Clear[g,a];
g[x_]=Expand[(a+x)^3];
g[13]

Out[4]=
27 + 27*a + 9*a^2 + a^3


In the next line (lhs):=(rhs) works
even though (x=3).

In[5]:=
Clear[g];
g[x_]:=Expand[(a+x)^3];
g[13]

Out[5]=
2197 + 507*a + 39*a^2 + a^3


Why do I say you should do this "whenever practical"?
Well the delayed versions of Rule, Set, UpSet,
and TagSet delay evaluation of (rhs). Sometimes you
don't want to delay evaluation of (rhs). In that
case you can solve the problem by doing so in a
Block as "Dr Dan" did.

But it's rather awkward to use something like:
Block[{x}, expr/.
Log[(x_+y_)^4]->Log[Expand[(x+y)^4]]
]

To make this situation a little nicer I wrote a package
that defines four new functions that work just like
Rule, Set, UpSet, and TagSet except a local environment
is used for any variables that have pattern names. I also
defined infix notation for the new functions.

If you want to take a look I can email you the package with
examples in a notebook. I sent the package to MathSource,
but I need to make provide more discussion before it will be
accepted.

-------------------
Note:
It's safe to use named patterns on the left hand side of
Rule, Set, UpSet and TagSet provided the variables aren't
used on the right hand side.

Example:
The next example comes out right because (x) isn't used
on the right side of (=).


In[6]:=
Clear[h]
x=0;
h[x_]/;(x>1)=100;
h[4]

Out[9]=
100

----------------------
Regards,
Ted Ersek


Earlier message from "Dr Dan" is copied below.
-----------------------

I am having trouble with name conflicts between global symbols and
named patterns.

This example from The Book works fine:

In[1]:= f[a^b] /. f[x : _^n_] -> p[x, n]
Out[1]= p[a^b, b]

But if the symbols used as pattern names have values:

In[3]:= n = 2; x = 3;
f[a^b] /. f[x : _^n_] -> p[x, n]
Out[3]= p[3, 2]

My usual favorite scoping structure, Module, doesn't help:

In[4]:= Module[{x, n}, f[a^b] /. f[x : _^n_] -> p[x, n]]
Out[4]= p[3, 2]

This shows that the global symbol is used as the pattern name and not
the symbol local to the scoping construct:

In[5]:= Module[{x, n}, Clear[x, n]; f[a^b] /. f[x : _^n_] -> p[x, n]]
Out[5]= p[3, 2]

Since local symbols are ignored, it is necessary to use Block:

In[6]:= Block[{x, n}, f[a^b] /. f[x : _^n_] -> p[x, n]]
Out[6]= p[a^b, b]

This looks like a bug to me. If I use a symbol in a local context I
expect the local symbol and never the global. I am a little concerned
that the pattern itself doesn't scope its pattern names, that I can
make one seemingly small change in my notebook and my patterned
replacements begin crashing.

Any comments, or a better workaround than Block?


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


0 new messages