Why can't I remove Orderless from Plus?


I am making some random algebra equations, and I want to have the ordering be random too, such that if my random equation generator makes x+1, the output stays x+1, without reverting to 1+x.

I have tried ClearAttributes[Plus, Orderless], but it simply did not work - entering x+1 returns 1+x.

The following sort-of works:

Format[Plus[a_, b_]] := ToString@a <> " + " <> ToString@b

But it uses Unprotect, converts everything to strings, and also doesn't work when b is a fraction (fractions p/q are represented as p\n--\nq).

Is there a nicer way to do this?

Also, I plan to convert everything to TraditionalForm at the end, so using that to control ordering won't work either.


Posted 2012-11-04T19:01:55.527

Reputation: 4 472

I found another solution, which is again not that great (as in it is super slow), but at least it gives me the results I want: Rasterize[TraditionalForm[a]]+Rasterize[TraditionalForm[b]] – VF1 – 2012-11-04T19:18:14.957

What exactly are you trying to do? I see the problem but I don't understand the objective well enough to offer alternatives. Your suggested fix still makes x+1 turn into 1+x, right? – Rojo – 2012-11-04T19:26:41.860

1@Rojo actually, don't worry about it. I figured it out. plus = Row[{#1, " + ", #2}] &; was what I was looking for: x~plus~1 // TraditionalForm gives exactly what I want. – VF1 – 2012-11-04T19:29:49.333

Yeah, that would work for 2 arguments, for more you can use Riffle. Row@Riffle[{##}, " + "] &. I would prefer using that as Format to plus more than as an ownvalue. Something like Format[plus[args__]] := Interpretation[HoldForm[Plus[args]], plus[args]] – Rojo – 2012-11-04T19:49:42.623

2Also, perhaps you would like wrapping your code in Module (or Block, depending on what you are doing) with Plus=plus, so you can use the + symbol at will. Module[{Plus = plus}, x + 1] – Rojo – 2012-11-04T19:50:49.563

@Rojo I find it interesting though, that after ClearAttributes[Plus, Orderless], MMA still returns 1+x even for Plus[x,1] input. – VF1 – 2012-11-06T03:49:13.617



With the suggested edits from Rojo in the comments above, the following is what answers my question:

plus[args__] := Row[Riffle[{args}, " + "]]

Then, Block[{Plus = plus}, x + 1 + i + 4 + z] // TraditionalForm returns:

enter image description here


Posted 2012-11-04T19:01:55.527

Reputation: 4 472

Looks good, +1. The idea of using Interpretation however was so that the output, if used literally as input, would be interpreted as ´plus[x,1,y...]if you wanted to further operate on that, even though it "looks like" plus. If you care about that then the second argument shouldn't be ´Row[Riffle... but plus[args]. If you don't care about that then you can do without ´Interpretation´ and use your Row@Riffle or that HoldForm@Plus – Rojo – 2012-11-06T05:53:30.393

@Rojo Yes - the whole point was just presentation anyway. But do you have any ideas as to why ClearAttributes didn't work? – VF1 – 2012-11-06T06:54:21.840

sorry for the late response. I was planning on digging into it before answering, but got sidetracked and lazy. So far I hadn't thought of a good reason why, and my lack of humility makes my ignorance default to "bug" – Rojo – 2012-11-19T19:05:02.920

1Hmmm... what about if he has terms with negative coefficients? – JohnD – 2013-08-16T23:56:19.003

@JohnD - It's interesting you pointed that out. That issue was actually resolved in another question. A combination of that answer and maybe some tinkering should do the job.

– VF1 – 2013-08-19T05:43:12.523