2
$\begingroup$

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:

  1. The first line works as expected, repeatedly dividing 80 by 2 until it's no longer even, and returning 5.
  2. In the last line, 80 is matched as EvenQ, and so we run the RHS of the rule a/2, but this time the a no longer refers to the matched number (80), but to the global variable a, and so it returns 3/2 and stops, because 3/2 is 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:

  1. Is my understanding correct?
  2. 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?
  3. 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 Module the only solution?
$\endgroup$
4
  • 5
    $\begingroup$ Use RuleDelayed: a = 3; 80 //. a_?EvenQ :> a/2 $\endgroup$ Commented May 21, 2023 at 18:17
  • $\begingroup$ Ah, that's exactly what I wanted. I get how it works now. If you post this as an answer I will accept it. $\endgroup$ Commented May 21, 2023 at 18:23
  • 2
    $\begingroup$ The rule of thumb, is that whenever the pattern name shows on the left and right side, use :> and not ->. see Wagner book example screen shot $\endgroup$ Commented May 21, 2023 at 18:29
  • $\begingroup$ You might look at 22917, especially the suggestion to use Trace. $\endgroup$ Commented May 21, 2023 at 18:56

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.