RE: Pure Functions in rules
- To: mathgroup at smc.vnet.net
- Subject: [mg15976] RE: [mg15932] Pure Functions in rules
- From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
- Date: Fri, 19 Feb 1999 03:26:59 -0500
- Sender: owner-wri-mathgroup at wolfram.com
When you use {1,2,3}/. (m_List->(2*#& /@ m)) (2*#& /@ m) evaluates before the replacement is made. To see what it evaluates to see Out[1]. In[1]:= Clear[m]; 2*#&/@m Out[1]= m So what you end up doing is simply {1,2,3}/.m_List->m ________________________________ Instead you should use (:>) instead of (->) as in In[2]. When you do it this way (2*#& /@ m) doesn't evaluate until m={1,2,3}. In[2]:= {1,2,3}/.(m_List:>(2*#& /@ m)) Out[2]= {2,4,6} _____________________ Now I give you another reason to prefer (:>) over (->). Suppose (m) has a global value as below. In[4]:= m=Log[5]; In[5]:= .... .... Then you do a lot of work, and forget about your previous use of (m). .... .... Now you try to use (->) in a case where it worked before, and your stunned by the result at Out[87]. I have yet to find a book about Mathematica that warns users about this, and I am puzzled way none of the authors discuss this point. In[87]:= {1,2,3}/.m_List->2*m Out[87]= 2 Log[5] _______________________ If you use (:>) you get the right result even though (m) has a value assigned to it. In[88]:= {1,2,3}/.m_List:>2*m Out[88]= {2,4,6} In general you shouldn't use (lhs->rhs) if (lhs) contains a named pattern and the name of the pattern is used in (rhs). Notice the next line comes out right because (m) isn't used on the right hand side of (->). You only have trouble when the name of the pattern is used on the right hand side of (->). In[89]:= {1,2,3,4,5,6}/.m_?EvenQ->0 Out[89]= {1,0,3,0,5,0} Actually there is a way to always get the right result using (lhs->rhs). You have to use Block (as below), but this is more complicated than (lhs:>rhs). In[90]:= Block[{m},{1,2,3}/.m_List->2*m] Out[90]= {2,4,6} In[91]:= m Out[91]= Log[5] At Out[90] we got the right result even though (m) still has the value Log[5]. Regards, Ted Ersek _______________________ Will Self wrote: It appears that I cannot depend on using a pure function in a pattern-matching rule. Here I am trying to convince reluctant students that they're better off learning to use Mathematica than doing things by hand, and we run across something like this, and in a much more complicated situation where the trouble was hard to isolate. I am quite frankly incensed by the behavior shown in In/Out 80, below. Look at these examples: In[73]:= {1,2,3}/.(m_List->7) Out[73]= 7 In[74]:= {1,2,3}/.(m_List->(2*m)) Out[74]= {2,4,6} In[75]:= 2*#& /@ {1,2,3} Out[75]= {2,4,6} In[77]:= f[m_List]:=2*#& /@ m In[78]:= f[{1,2,3}] Out[78]= {2,4,6} In[79]:= {1,2,3}/.m_List->f[m] Out[79]= {2,4,6} Now try this: In[80]:= {1,2,3}/.(m_List->(2*#& /@ m)) Out[80]= {1,2,3} Does anyone (say, at WRI for example) care to comment on this? Will Self