12

I am a beginner exploring the world of Mathematica. I expected the following code

T[6, 5, 4, 1, 2, 3] /. {T[a___, 1, b___] -> Length[List[b]]}

should return the value 2, rather than 1. Anyone could explain where I was wrong?

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
Joonho Kim
  • 445
  • 2
  • 9

2 Answers2

20

This is because the code Length[List[b]] is evaluated before the rule is applied. Using RuleDelayed rather than Rule would fix it:

T[6, 5, 4, 1, 2, 3] /. {T[a___, 1, b___] :> Length[{b}]}

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
mmjang
  • 2,583
  • 20
  • 26
10

The function Trace can be helpful in diagnosing the problem. The documentation says:

Trace returns a set of nested lists. Each individual list corresponds to a single evaluation chain, which contains the sequence of forms found for a particular expression. The list has sublists which give the histories of subsidiary evaluations.

With your input:

Trace[
  T[6, 5, 4, 1, 2, 3] /. {T[a___, 1, b___] -> Length[List[b]]}
]
{{{{Length[{b}],1},T[a___,1,b___]->1,T[a___,1,b___]->1},
 {T[a___,1,b___]->1}},T[6,5,4,1,2,3]/.{T[a___,1,b___]->1},1}

Observe that the first evaluation chain is {Length[{b}],1} which clearly shows the problem. Now compare the Trace when correctly using RuleDelayed:

Trace[
  T[6, 5, 4, 1, 2, 3] /. {T[a___, 1, b___] :> Length[List[b]]}
]
{{{T[a___,1,b___]:>Length[{b}],T[a___,1,b___]:>Length[{b}]},
{T[a___,1,b___]:>Length[{b}]}},T[6,5,4,1,2,3]/.
{T[a___,1,b___]:>Length[{b}]},Length[{2,3}],2}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371