RE: Scoping and named patterns

*To*: mathgroup at smc.vnet.net*Subject*: [mg18169] RE: [mg18132] Scoping and named patterns*From*: "Ersek, Ted R" <ErsekTR at navair.navy.mil>*Date*: Sat, 19 Jun 1999 23:54:30 -0400*Sender*: owner-wri-mathgroup at wolfram.com

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