2

Related to this question,

Why does this InterpretationBox construct work when x, y are numbers but not undefined symbols or more complex expressions?

foo /: MakeBoxes[c : foo[x_, y_], form : (StandardForm | TraditionalForm)] := With[{boxes = SubscriptBox[x, y]}, InterpretationBox[boxes, c]]

EDIT

Originally intended to state the full problem but then simplified it. kglr's answer does not work as intended, so here is the complication:

Would like foo[r,m] to display in subscript form, but when provided with a SubValue, it should evaluate to the rhs:

foo[r_,m_][h_]:= m h + r

END EDIT

Works:

foo[2,3]

Subscript[2, 3]

Plugging in x inserts $CellContext:

foo[2, x]

Subscript[2, $CellContext`x]

or fails with List:

foo[{1, 2}, 3]

An unknown box name (List) was sent as the BoxForm for the expression. Check the format rules for the expression.

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
alancalvitti
  • 15,143
  • 3
  • 27
  • 92

2 Answers2

3

Answering the title question, when creating boxes, everything should be a *Box object or a string (or possibly a list). Inside of a box object, excluding options, again, everything should be a *Box object or a string (or list). There is one exception to this rule. It is ok to use integers instead of the corresponding strings. I'm not sure why this exception is made, as it results in the confusion that you face when using x instead of 1 breaks things.

As for the actual format code, another possibility is:

foo /: MakeBoxes[foo[x_, y_], form_] := MakeBoxes[Subscript[x, y], form]

Finally, I think your edited issue is that you included ClearAll[foo] after defining the subvalue definition.

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
1

Replace boxes = SubscriptBox[x, y] with SubscriptBox[ToBoxes@x, ToBoxes@y]:

ClearAll[foo]
foo /: MakeBoxes[c : foo[x_, y_], form : (StandardForm | TraditionalForm)] := 
 With[{boxes = SubscriptBox[ToBoxes @ x, ToBoxes @ y]}, InterpretationBox[boxes, c]]

Examples:

foo[2, 3]

Subscript[2, 3]

foo[2, 3]

Subscript[2, x]

foo[{a, b}, {1, 2, 3}]

Subscript[{a,b}, {1,2,3}]

As suggested by @Kuba in comments, use

boxes = SubscriptBox[MakeBoxes @ x, MakeBoxes @ y]

to avoid evaluation leaks in cases like Hold @ foo[f[1 + 2], x + y].

kglr
  • 394,356
  • 18
  • 477
  • 896
  • 1
    MakeBoxes should be used to avoid evaluation leaks when things like Hold @ foo[1+1, 2] are being (?)typeset. – Kuba Aug 21 '19 at 07:07
  • Thank you @Kuba; excellent point. I will update with your suggestion if you do not intend to post it as an answer. – kglr Aug 21 '19 at 07:12
  • Sure, a separate answer is not needed. – Kuba Aug 21 '19 at 07:18
  • @kglr Thanks, however, this doesn't work with my intended application, which is to have SubValues for foo. I originally intended to add this bit but in the end decided to simplify it. Will edit Q. – alancalvitti Aug 21 '19 at 18:17
  • @Kuba, please see edit - do I need to ask as a separate Q? – alancalvitti Aug 21 '19 at 18:25
  • @alancalvitti afaict Carl's answer is what I consider the answer. Or did I miss the point? – Kuba Aug 22 '19 at 07:42
  • @kglr, @Kuba, boxes = SubscriptBox[MakeBoxes @ x, MakeBoxes @ y] doesn't work. It doesn't evaluate the SubValue – alancalvitti Aug 28 '19 at 18:17