I don't understand why $a$ and $b$ are not local in the following code:
Clear[lint];
lint[f_, x_] := Module[{a, b}, f /. Replace[x, {a_, b_} -> a -> b]];
Clear[a];
lint[x, {x, t}] (* returns t, as I would expect *)
a = 3;
lint[x, {x, t}] (* returns x *)
Clear[a]; a=3;
lint1[f_, x_] := Module[{a, b}, f /. Replace[x, {a_, b_} :> a -> b]]; (* returns t *)
It appears that the occurrence of $a$ in the pattern inside the replace is being interpreted in the outer scope. Why is that?
Update: Having read @szabolcs comment and the first answer, I still don't quite understand. First, the documentation for Rule says that "Symbols that occur as pattern names in lhs are treated as local to the rule.". Fine, that's what the comment said. But if they are local, then why is $3$ substituted for $a$ in the second example above?
Second, why does using :> solve the problem? The only difference between Rule and RuleDelayed, as far as I can see, is when the right-hand symbols are evaluated. So why does this change the behavior? (See the new fourth example above).
Moduleis unnecessary. If you useRuleDelayedinstead ofRule, then the pattern variables are automatically localized.lint2[f_, x_] := f /. Replace[x, {a_, b_} :> a -> b]– rm -rf Feb 15 '14 at 16:10Ruleitself is a sort of scoping construct in Mathematica and it will protect symbols that are used as pattern names in its LHS from being renamed by Module. – Szabolcs Feb 15 '14 at 16:34Rule. – rogerl Feb 18 '14 at 02:37Rulethe symboladoes not appear on the rhs, because the rhs is evaluated beforeRule"sees it". So the rule is:{a_, b_} -> (3 -> b). Since the symbolsaandboccur as pattern names in the lhs of this rule, they are indeed treated as local to the rule, but this localisation happens after the evaluation of the rhs.RuleDelayedhas theHoldRestattribute, so the rhs doesn't get evaluated and the rule acts as you expect. – Simon Woods Feb 18 '14 at 13:41a = "outside"; Module[{a = "inside"}, 1 /. a_Integer -> a]. This one returns"outside", not"inside". We told you that bothModuleandRuledo some kind of localization. But the end result is thatadoesn't get localized at all and it's evaluated to its global value. Of course this is extremely confusing! But it's how the system works (i.e. doing "localization" via renaming) and we cannot change it. – Szabolcs Feb 18 '14 at 18:07Moduledoes localization by renaming variables before evaluation, as you can see by evaluatingModule[{x}, x]. However, it does not rename everything. Things inside other scoping constructs insideModuledo not always get renamed. I do not fully understand when this renaming happens and when it doesn't, nor why (and when) it is necessary. It a very dark corner of Mathematica. The rest is explained by the answers: sinceRuleis a kind of scoping construct, it prevents Module from renaminga, so we still haveainstead ... – Szabolcs Feb 18 '14 at 18:19a$123(i.e. the "localized" version).ais a global symbol which has a value, to which it gets evaluated. Again the thing to pay attention to here is that there aren't really any local and global variables in Mathematica, only renamed or non-renamed ones. (Side note: WhatBlockdoes is that it temporarily removes the definitions associated with symbols, but the symbols themselves stay the same.) – Szabolcs Feb 18 '14 at 18:21