MathGroup Archive 1999

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

Search the Archive

RE: Scoping and named patterns

Dr Dan  (drdanw at  
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)


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

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

p[a^b, b]
Here (x=3) from the line above
so (lhs)=(rhs) doesn't work right.


27 + 27*a + 9*a^2 + a^3

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


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

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 

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.

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



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
Share what you know. Learn what you don't.

  • Prev by Date: Re: Equality of integrals
  • Next by Date: RE: Dealing with submatrices
  • Previous by thread: Re: Scoping and named patterns
  • Next by thread: Re: Scoping and named patterns