Re: Weird localization bug!
- To: mathgroup at smc.vnet.net
- Subject: [mg106047] Re: Weird localization bug!
- From: "Norbert P." <bertapozar at gmail.com>
- Date: Thu, 31 Dec 2009 03:16:00 -0500 (EST)
- References: <hhf5pa$h0e$1@smc.vnet.net>
On Dec 30, 1:16 am, Derek Yates <yat... at mac.com> wrote: > I can't figure this out, and think it is a bug. I'm using Mathematica > 7.0.0 and get the same behaviour on both Mac OS X (10.5.8) and on > Windows XP. > > I want a function which creates a rule. The rule is of the form > "manipulated input" -> "input". Here is my first attempt (I have > simplified from what I really want to do, in order to illustrate the > bug): > > (1) makerule[input_] :=(input /. a_Integer :> 2 a) -> input > In: makerule[5] > Out: 2a->5 > > (I expect to get 10->5) > > (2) makerule2[input_] := (input /. a_Integer :> 2 a)~myrule~input > In: makerule2[5] > Out: myrule[10,5] > > as expected > > Forcing an extra layer of localization seems to squash the bug: > > (3) makerule3[input_] :=Block[{inputcopy = input},(input /. > a_Integer :> 2 a) -> inputcopy] > In: makerule[5] > Out: 10->5 > > Is it a bug, or have I misunderstood how the localization is meant to > work? This is gonna be one of these weird Mathematica features that surprise me every day. I played around with your code (Mathematica 6.0.2) and this occurs for any of the lexical scoping constructs: function definition, rule and With. But only when the value is inserted in the right-hand side of a rule, as in: With[{x = 2}, (2 /. a_ :> 2 a) :> x] but not in With[{x = 2}, (x /. a_ :> 2 a) :> 2] One can see what is happening using Trace: In[1]:= Trace[With[{x=2},(2/.a_:>2a):> x]]//Column Out[1]= With[{x=2},(2/.a_:>2 a):>x] (2/.a$_:>2 a):>2 {{a$_:>2 a,a$_:>2 a},2/.a$_:>2 a,2 a} 2 a:>2 2 a:>2 You can see that the localization renames a to a$, but only on the left-hand side of the rule. And this is imho wrong. Even simpler: In[2]:= Trace[With[{x=2},(a_:>a):> x]]//Column Out[2]= With[{x=2},(a_:>a):>x] (a$_:>a):>2 {a$_:>a,a$_:>a} (a$_:>a):>2 (a$_:>a):>2 but In[3]:= Trace[With[{x=2}, a_:>a x]]//Column Out[3]= With[{x=2},a_:>a x] a$_:>a$ 2 which gives the correct result, even though the renaming is completely unnecessary. Compare with In[4]:= Trace[With[{x=2}, x a_:>a ]]//Column Out[4]= With[{x=2},x a_:>a] 2 a_:>a No renaming. Very interesting ;)) Best, Norbert