Consider the following:
80 //. a_?EvenQ -> a/2 a = 3 80 //. a_?EvenQ -> a/2 which outputs:
5 3 3/2 I think I understand what is happening:
- The first line works as expected, repeatedly dividing 80 by 2 until it's no longer even, and returning 5.
- In the last line, 80 is matched as
EvenQ, and so we run the RHS of the rulea/2, but this time theano longer refers to the matched number (80), but to the global variablea, and so it returns3/2and stops, because3/2is not even any longer.
Point 2 surprised me because I had assumed that a kind of "local scope" would be created by a once the match took place, and indeed within the match this is true -- a must be referring to 80. So "the thing a refers to" changes between the matching phase and the execution phase of the rule.
I understand that I can use Module to avoid this behavior but my questions are:
- Is my understanding correct?
- From a language design perspective, why does it work this way? In what contexts, for what problems, would one want it to work to work this way?
- When you don't want it work this way, but instead want the rules to be interpreted with local scope, and to ignore any conflicting global names, is
Modulethe only solution?
RuleDelayed:a = 3; 80 //. a_?EvenQ :> a/2$\endgroup$:>and not->. see Wagner book example screen shot $\endgroup$Trace. $\endgroup$