Why doesn't defined MakeBoxes display what is constructed in RHS?

Inspired by the @ybeltukov 's answer to this question, if I have the following polynomial

poly = a^2 + (a^2 + b^2 - c^2)*x + b^2*x^2;
var = x;

this generates boxes out of a polynomial to be displayed in canonical order:

MakeBoxes[+##] & @@ (var^#1[] #2 & @@@ CoefficientRules[poly, var])

$b^2 x^2 + (a^2 +b^2 -c^2)x + a^2$

But if I use the same construction to define MakeBoxes for my function mypoly in TraditionalForm

MakeBoxes[+##] & @@ (var^#1[] #2 & @@@ CoefficientRules[poly, var])

mypoly[a^2 + x^2 b^2 + x (a^2 + b^2 - c^2), x] // TraditionalForm

does not yield the correct order:

$x(a^2 +b^2 -c^2) + a^2 +b^2 x^2$

Why? and what can I do to get the right order?

• not really an answer, but if you put an HoldForm around the +## in MakeBoxes it works: MakeBoxes[mypoly[poly_, var_], TraditionalForm] := MakeBoxes[HoldForm[+##]] & @@ (var^#1[] #2 & @@@ CoefficientRules[poly, var])
– glS
Aug 13 '16 at 15:03
• @gIS but it is an answer. I'll try it out as soon as I get my hands on Mathematica. Aug 13 '16 at 17:00
• well, I mean, it solves the problem but as the question was about why this happens, I'm not really able to answer that! Clearly something about the order things are evaluated but I was not able to pinpoint it exactly. Something interesting is that adding that HoldForm changes the output only in that it wraps the resulting expression into a TagBox, which again I'm not really sure what it does (the docs say that TagBox somehow helps "guiding the interpretation of the boxes")
– glS
Aug 13 '16 at 17:11
• I had no idea you could do +##, nice trick. Aug 19 '16 at 13:31
• @masterxilo Thanks, but it's actually from ybeltukov's answer in the link given at top. Aug 19 '16 at 13:43

Interesting question. Building on comments by glS It appears that HoldForm is treated specially by (conversion to) TraditionalForm, whereas a normal hold attribute does not prevent reordering. This is not exactly surprising considering that formatting rules do not directly respect hold attributes. (See Returning an unevaluated expression with values substituted in.)

Here is a concise example:

{HoldForm[b + a^2], Defer[b + a^2], HoldComplete[b + a^2]} // TraditionalForm Note that neither Defer nor HoldComplete prevent this reordering. So while MakeBoxes has HoldAllComplete this is insufficient to preserve order.

Further, Box form is itself vulnerable to reordering by TraditionalForm:

MakeBoxes[b + a^2]
RowBox[{"b", "+", SuperscriptBox["a", "2"]}]

a^2 + b

Note that the RowBox is in the correct order but the second line still alters its order.

One finds that HoldForm becomes a TagBox upon box conversion. Interestingly it seems that an arbitrary TagBox also prevents this reordering:

TagBox[RowBox[{"b", "+", SuperscriptBox["a", "2"]}], foo] //