How do I stop recursion happening in a Format/Interpretation Mathematica construction?
This question follows on from the answer given by Michael 开发者_如何学编程Pilat in Preventing “Plus” from rearranging things. There he defined a custom +
notation using
Format[myPlus[expr__]] := Row[Riffle[{expr}, "+"]]
The problem with this is you can't copy and paste the output (although % or Out[] still works). To get around this you should use the Interpretation
type facility which allows an expression to be displayed as one thing, but interpreted as another when supplied as input. My modification of Michael's answer is
Format[myPlus[expr__]] := Interpretation[Row[{expr}, "+"], myPlus[expr]]
This can be copied and pasted successfully. The problem lies in modifying copied expressions. You can convert a copied expression back to InputForm
using Ctrl-Shift-I
then change anything you want and use the InputForm
in any expression. But if you try to change it back to StandardForm
using Ctrl-Shift-N
then you enter an recursion where the second argument in the Interpretation
repeatedly gets evaluated. This is despite Interpretation
having the attribute HoldAll
(which works properly during normal evaluation).
Normally, when defining simple notations I use the low-level MakeBoxes
, eg
myPlus/:MakeBoxes[myPlus[expr__],fmt_]:=With[{r=Riffle[MakeBoxes/@{expr},"+"]},
InterpretationBox[RowBox[r],myPlus[expr]]]
which works perfectly, so I have not encountered this recursion problem before.
So my question (finally) is:
What went wrong with my Format
type command and how can it by fixed?
Or: How do you make a high-level equivalent of my MakeBoxes
type command?
I consulted with a colleague about this, and his recommendation was essentially that putting up-value definitions on MakeBoxes
as you demonstrate is better than using Format
when you want things to be tightly integrated from output back to input. Format
isn't really intended to produce output that can be re-used as input, but just to format output, hence the unexpected recursion with Interpretation
when converting to StandardForm
, etc.
You might find the function ToBoxes
a useful complement to MakeBoxes
.
Finally, here's a tutorial about box structures.
HTH!
精彩评论