In two recent questions (1, 2), the previous posters were attempting to control the output order of Plus
, which is an Orderless
function. Michael Pilat indicated that, internally, Orderless
functions Sort
their parameters which was causing the difficulty. However, he cautioned against making Plus
non-Orderless
. The solutions to the two previous questions amount to creating a function that displays like Plus
but is not Orderless
itself. This is certainly effective, but my question is how can we change the default Sort
order?
I need to do a little more research, but here's two ways; The catch is, you don't actually use the Orderless
attribute. Simon should get half-credit for the technique of using pattern-matching with a condition from his answer to question 1 you referenced.
Messing with Order
, OrderedQ
and Sort
won't get you anywhere, because Orderless
functions sort with equivalence to those methods, but does not actually sort with them.
The first method, from Simon's answer, is to use a Condition
:
In[1]:= ClearAll[f, g]
In[2]:= f[stuff__] /; ! OrderedQ[{stuff}, Greater] :=
f[Sequence@@Sort[{stuff}, Greater]]
In[3]:= f[1, 2, 3]
Out[3]= f[3, 2, 1]
In[4]:= f[3, 2, 1]
Out[4]= f[3, 2, 1]
That definition of f[stuff__] is evaluated if the order of the arguments is not the order desired, and then transformed into that order.
Another technique is to get a little more low-level and use $Pre
or $PreRead
:
In[5]:= $Pre =
Function[{expr},
expr /. g[stuff__] :> g[Sequence @@ Sort[{stuff}, Greater]]];
In[6]:= g[1, 2, 3]
Out[6]= g[3, 2, 1]
In[7]:= g[3, 2, 1]
Out[7]= g[3, 2, 1]
There are some issues with both of these approaches as they stand, for example, that particular $Pre
function doesn't play well with e.g. HoldForm[g[1,2,3]]
.
So, that's something to play with for now. I hope to update after I do a little more research into this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With