Consider the following Mathematica pattern transformation:
In[1]:= 2 x /. a_ b_ :> {a, b}
Out[1]= {2, x}
No surprises there. But watch what happens if you change the pattern variable a
to z
:
In[2]:= 2 x /. z_ b_ :> {z, b}
Out[2]= {x, 2}
The result elements are reversed, just because a variable was renamed. What happened?
This behaviour is by design. It occurs because of two points. The first is that the patterns on the left-hand side of replacement rules are evaluated. In this case, z_ b_
will be evaluated. The second point is that *
(Times
) has the attribute Orderless
. This means that the arguments to the function are sorted into canonical order prior to evaluation. We can see the effect of this canonical ordering on the replacement rule that uses z_
:
In[3]:= z_ b_ :> {z, b}
Out[3]= b_ z_ :> {z, b}
The pattern is reversed. This explains the difference between the two replacements. Is there anything we can do to avoid this? Well, we could hide the Times
operator from evaluation:
In[4]:= 2 x /. Verbatim[Times][z_, b_] :> {z, b}
Out[4]= {2, x}
This "works", but is fragile. In a toy example like this, we can control the points where the pattern gets evaluated. But in more realistic examples, it is easy to accidentally evaluate the relevant part of the pattern, resulting in the variable swap. So the bottom line is that one must be very careful when writing patterns involving orderless operators. Especially when the pattern is being used to transform the orderless operator into an operator that is sensitive to order. Note that this problem would not be observed if the target operator were orderless as well:
In[5]:= 2 x /. a_ b_ :> a + b
Out[5]= 2 + x
In[6]:= 2 x /. z_ b_ :> z + b
Out[6]= 2 + x