Re: Weird localization bug!
- To: mathgroup at smc.vnet.net
- Subject: [mg106060] Re: [mg106009] Weird localization bug!
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Thu, 31 Dec 2009 03:18:29 -0500 (EST)
- References: <200912300913.EAA17160@smc.vnet.net>
Hi Derek, This indeed looks like a bug to me. Tracing the execution allows to reveal some details: In[1]:= makerule[5]//Trace Out[1]= {makerule[5],(5/.a$_Integer:>2 a)->5,{{a$_Integer:>2 a,a$_Integer:>2 a},5/.a$_Integer:>2 a,2 a},2 a->5,2 a->5} The real problem is that <input> is present in the definition *and* the both sides of the rule <(input /. a_Integer :> 2 a) -> input>. It is well-known that Mathematica does aggressive dummy (pattern) variable renaming whenever it suspects a name collision in nesting lexical scoping constructs. Both Rule and RuleDelayed are scoping constructs, therefore placing rule within a rule where some of the pattern names are present in both external and internal rules (<input> in this case) is an invitation for the Mathematica variable-renaming mechanism. In this case, however, the renaming was obviously inconsistent - <a> was renamed to <$a> only on the left-hand side of the delayed rule. My guess would be that the binding in the internal RuleDelayed is performed at an earlier stage, since in nesting the scoping constructs the usual Mathematica convention is that inner scopes are favored in name collisions (but again, Rule and RuleDelayed do not always obey this convention). Then <a> gets replaced by <$a> indeed everywhere, but then the just mentioned internal binding sets the r.h.s. back to <a>. Regardless of whether or not this is indeed what happens, the final result is IMO not what it should have been. It is easy to see that the problem shows up "dynamically" during the rule application rather than when the definition is given: In[2]:= Hold[makerule[5]] /. DownValues[makerule] Out[2]= Hold[(5 /. a$_Integer :> 2 a) -> 5] Why the same did not happen in the second case is beyond me. Perhaps wrapping your numbers in <myrule> means for RuleDelayed that there is no nesting of scoping, since <myrule> is not a scoping construct (while Rule is a scoping construct and thus there is direct nesting), and therefore renaming is not attempted. In the last case you seem to have blinded the renaming mechanism by using Block (the latter being a dynamic scoping construct). In any case, this looks like a bug. Regards, Leonid On Wed, Dec 30, 2009 at 1:13 AM, Derek Yates <yatesd 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? > >
- References:
- Weird localization bug!
- From: Derek Yates <yatesd@mac.com>
- Weird localization bug!