Schrödinger's MatrixForm: feature or bug?
Here are few notes:
Notice the second argument of underying TagBox[gridbox, Function[e, MatrixForm[e]]
. It guides the interpretation from standard to input form (Ctrl+Shift+I). Since MatrixForm
won't be forgotten, route back to boxes works too.
It is not documented but it seems to work like ToExpression[gridbox, StandardForm, Function[...]]
. It won't work manually, ToExpression@ToBoxes@MatrixForm
will return an array. Whether that is expected I don't know but I think this should be more consistent.
Here is another example (bug) showing the difference between Cell/ConvertTo items and composition of ToBoxes/Expression:
TagBox + InterpretationBox vs ConvertTo/StandardForm
Summing up:
Ctrl+Shift+I behavior is governed by
TagBox
(fine but undocumented)ability to evaluate typeset
MatrixForm
comes from the fact thatToExpression
strips it before parsing/evaluation. (arguable)
This is essentially a duplicate of this question:
- When typesetting as output,
MatrixForm[_?ArrayQ]
will display matrix-like. - In an output cell, Convert To StandardForm will default to box formatting, so you go back and forth between a matrix-like state and an
InputForm
-like state. - Once you edit the cell becomes an Input cell, so now
MatrixForm
will use an input-form like state for Convert To StandardForm.
So what's going on with that TagBox
, and how does ToExpression@ToBoxes@...
produce a list? Well, normally the second argument of a TagBox
, in the absence of more specific rules, is applied as the head of the expression generated from the first argument:
MakeExpression[TagBox["a", b], StandardForm]
(* HoldComplete[b[a]] *)
However, an exception is made for heads that are members of $OutputForms
, where it is ignored:
$OutputForms // Unprotect
AppendTo[$OutputForms, b]
MakeExpression[TagBox["a", b], StandardForm]
(* HoldComplete[a] *)
This is "wrapper stripping" (the behavior of functions that "affect formatting, but not evaluation") is implemented. But it would be bad if wrapper stripping occured when you did a Convert To *Form. Fortunately, that operation doesn't use MakeExpresion/MakeBoxes
, but rather a dedicated function, which knows not ignore those TagBox
es. Here is the call to convert from StandardForm
to InputForm
:
BoxForm`ConvertForm[TagBox["a", b], StandardForm, InputForm]
(* "b[a]" *)
To be perfectly honest, the only reason I can explain this behavior is that I came across the source code for it while fixing a bug, and was able to reproduce the reason for it from the commit message. It is a bit of black magic, but given the relatively small number of questions about it for the last 24 years or so, it is good enough to get the job done.