6
$\begingroup$

What is the difference between the following two:

(*1: UpSet definition*)
myfuncF /: MakeBoxes[myfuncF[a_, b_], TraditionalForm] := 
  RowBox[{"f(", Sequence @@ Riffle[Map[ToBoxes, {a, b}], ","], ")"}]

and

(*2: MakeBoxes definition*)
MakeBoxes[myfuncF[a_, b_], TraditionalForm] := 
  RowBox[{"f(", Sequence @@ Riffle[Map[ToBoxes, {a, b}], ","], ")"}]

With myfuncF[a,b] // TraditionalForm I get for both the following output.

f(a, b)

Is one preferable over the other?

$\endgroup$
  • 3
    $\begingroup$ One observation here which I find interesting is that MakeBoxes is HoldAllComplete. This should mean that it doesn't perform any UpValue search. Yet, UpValue-based definitions do work with it. There must be something rather interesting going on there, but I never had the energy to investigate deeper. $\endgroup$ – Leonid Shifrin Oct 19 '14 at 20:29
  • $\begingroup$ @LeonidShifrin I remember from playing around some time ago that these don't set upvalues or downvalues but format values. If I remember correctly these are tried in the logical order but only after downvalues $\endgroup$ – Rojo Oct 20 '14 at 3:01
  • $\begingroup$ @QuantumDot if this is the case I would use the UpSet definition because once you clear myfuncF the definition is cleared too, but it doesn't seem like a big deal anyway $\endgroup$ – Rojo Oct 20 '14 at 3:03
  • $\begingroup$ @Rojo It turns out I can format things like $f^2(x,y)$ by using MakeBoxes[Power[myfuncF[a_, b_], n_], TraditionalForm] := RowBox[{SuperscriptBox["f", ToBoxes[n]], "(", Sequence @@ Riffle[Map[ToBoxes, {a, b}], ","], ")"}], which I cannot do using UpSet (since myfuncF would be too deep). $\endgroup$ – QuantumDot Oct 24 '14 at 11:32
  • $\begingroup$ @LeonidShifrin see my comment above to Rojo $\endgroup$ – QuantumDot Oct 24 '14 at 11:33
6
$\begingroup$

Generally speaking, that TagSetDelayed form is preferable, as the rule is attached to the myfuncF rather than to MakeBoxes. This means:

  1. Clear[f] will remove the FormatValues.
  2. The pattern is only matched against expressions which contain myfuncF rather than all expressions.
  3. The pattern won't compete against any other patterns attached to MakeBoxes (i.e, it's applied first)

As pointed out in some of the comments, this may not work if you have a specific rule for when myfuncF is embedded inside another expression. In that case you'll need to either attach the rule to that other head, or live with it being attached to MakeBoxes.

Note that whether you use SetDelayed or TagSetDelayed, neither an up value or a down value is created, but rather a format value.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.