Unexpected behavior of rule matching a pattern



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?

Joonho Kim

Posted 2013-04-08T08:06:57.670

Reputation: 445

Related: (13472), (24860), (26619)

– Mr.Wizard – 2015-07-15T06:39:44.633

4note that T is a bad choice of variable/function name. I suggest using names starting in lowercase letters, especially when using single letters. This avoids conflicts with built-ins (e.g. N, D...) – Pinguin Dirk – 2013-04-08T08:26:17.863



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}]}


Posted 2013-04-08T08:06:57.670

Reputation: 2 533


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:

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

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

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


Posted 2013-04-08T08:06:57.670

Reputation: 259 163

Thank you. This would be very helpful to understand the behavior of Mathematica. – Joonho Kim – 2013-04-09T23:23:12.497