1

This works:

(w[1] + w[2] + w[3]) /. w[s_] -> If[s == 2, w[s], 0]

(* w[2] *)

This doesn't:

(w[1] + w[2] + w[3]) /. w[s_] -> If[EvenQ[s], w[s], 0]

(* 0 *)

Why?

Jerry Guern
  • 4,602
  • 18
  • 47

1 Answers1

3

The second one does not work as intended because EvenQ[x] always returns False if x is not "manifestly an even integer" (quote from docs.) Since you use -> instead of :>, the expression If[EvenQ[s], w[s], 0] is evaluated at once, and since s is a symbol at that stage, it is not manifestly an even integer. The first example works because s == 2 is neither True nor False until s aquires a value, which happens after replacement. The second one works with RuleDelayed:

(w[1] + w[2] + w[3]) /. w[s_] :> If[EvenQ[s], w[s], 0]
(* w[2] *)
Marius Ladegård Meyer
  • 6,805
  • 1
  • 17
  • 26
  • 1
    @Jerry, it might help you to look at the analogy between the pairs =/:= and ->/:>; the ones on the left evaluate their right-hand sides at once, and the right ones don't. In your case, the instant evaluation resulted in an If[False, (* stuff *)]. – J. M.'s missing motivation Jul 22 '15 at 05:07
  • @J. M. I understand the instant vs. delayed evaluation thing now, but I still don't understand why this wasn't a problem for "s==2". Why doesn't that return False upon instant evaluation? – Jerry Guern Jul 22 '15 at 06:52
  • @Jerry, Equal does not evaluate at once unless both sides are numeric or manifestly equal, which is why it is useful for representing equations (e.g. in Solve[] and ContourPlot[]). – J. M.'s missing motivation Jul 22 '15 at 06:57
  • @J. M. So then, what is the purpose of "->"? Is it ever preferable to ":>"? Should we just use ":>" all the time? – Jerry Guern Jul 25 '15 at 11:17
  • 1
    If you have a fixed rule that you apply to a lot of expressions, it's wasteful to use the delayed one, because it evaluates each time. There are uses for both, just like there are uses for both = and :=. – Marius Ladegård Meyer Jul 25 '15 at 11:31