Unexpected side effect of removing the Orderless attribute from Times

First I make Times orderless:

ClearAttributes[Times, Orderless];


Then I evaluate

Expand[(x (y - z)]


which produces

x y + x (-1) z

But when I evaluate

Distribute[x (y - z)]


I get

x y - x z

This last is what I expected from both cases.

My question is: Why does this happen?

My interest is both academic and practical, since I would like to use things like ExpandAll later on my code.

-
It's generally not a wise idea to remove attributes from fundamental functions such as Times... – R. M. Mar 29 '13 at 16:45

If you look at the Fullform of the expression, you can see what's going on. When you set ClearAttributes[Times, Orderless] to

FullForm[Expand[x (y - z)]]


you get the form

Plus[Times[x,y],Times[x,-1,z]]


Since you told Times that it could no longer place the x and the -1 in normal order, it listed them in the order in which they appear in the expression. In fact, what Orderless does is to place elements in "canonical order". So when Times is used normally (with SetAttributes[Times,Orderless]) the FullForm[Expand[x (y - z)]] is

Plus[Times[x,y],Times[-1,x,z]]


which displays the way you expect. This is perhaps just a longer way to agree with rm -rf, if you go about changing the Attributes of fundamental functions then you should expect to see things that are odd.

-

First, you should never do this, except for fun.

One thing to keep in mind about Times and Plus is they have their own internal rules that will be applied no matter how you try to override them.

For me, the curious thing was why don't Expand and Distribute return the same thing? The result from Expand was what I expected.

First, try to mess things up:

Unprotect[Times];
ClearAttributes[Times, Orderless];
Protect[Times];


Next, replace Times and Plus with non-orderless place holders to see what Distribute does:

SetAttributes[f, {Flat, Listable, NumericFunction, OneIdentity}];
SetAttributes[g, {Flat, Listable, NumericFunction, OneIdentity}];

Distribute[x (y - z) /. {Times -> f, Plus -> g}, g, f]


g[f[x, y], f[x, -1, z]]

Now that's odd: the -1 is between x and z, like Expand but unlike the output from Distribute. Let's replace f, g, by Times and Plus:

g[f[x, y], f[x, -1, z]] /. {f -> Times, g -> Plus}
x y - x z


Hey, the -1 factor is now out in front.

What's going on?

There are internal rules that deal with numbers in ways that cannot be overridden. For instance:

Times[x, -1, z, 2] // Trace //InputForm


{HoldForm[x*-1*z*2], HoldForm[-2*x*z]}

You can see the numbers have been collected and combined. It appears that with Distribute (or ReplaceAll in my example), Mathematica is processing the internal expression an extra step or two, compared to Expand (use Trace). If you really need convincing, see if you can figure out the internal rules that put the numbers in this order:

2 x (x - 5 y ) (y - 3 z) // Expand


y x^2 2 - 6 z x^2 + y (-10) x y + z 30 x y

That's enough to convince me not to clear the Orderless attribute from Times.

Unprotect[Times];
SetAttributes[Times, Orderless];
Protect[Times];


Or maybe Quit[], to be on the safe side. :)

-