Mathematica Asked by N0va on January 11, 2021
I have a problem with the build-in Information
function for user-defined symbols with custom StandardForm in Mathematica 12.1.1.0:
For example with the function definitions
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := Row[{a, b}, " "]
CM::usage = "CM";
the query Information[CM]
results in:
The definitions in the output are formatted using StandardForm without even displaying it correctly. The same problem occurs when one defines UpValues. At this point this makes the Information box just unreadable but it gets worse when using InterpretationBox
. With
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b___], StandardForm] := With[{box = ToBoxes[Row[{a, b}," "]]},
RawBoxes[InterpretationBox[RowBox[{box}], CM[a, b]]]
];
CM::usage = "CM";
A call to Information[CM]
results in an infinite recursion and several warnings and errors:
Inspecting the FullForm
of the results of Information[CM]
reveals
InformationData[Association[
...
Rule["DownValues",Information`InformationValueForm[DownValues,CM,List[RuleDelayed[CM[1,Pattern[a,BlankSequence[]]],CM[a]]]]],
...
Rule["FormatValues",Information`InformationValueForm[FormatValues,CM,List[RuleDelayed[MakeBoxes[CM[Pattern[a,Blank[]],Pattern[b,BlankNullSequence[]]],StandardForm],Format[With[List[Set[box,ToBoxes[Row[List[a,b]," "]]]],RawBoxes[InterpretationBox[RowBox[List[box]],CM[a,b]]]],StandardForm]]]]],
...
]]
and with it the internal and of course undocumented function ...InformationValueForm
which is used to output the found definitions.
Is there a way to configure or manipulate Information
or the underlying InformationValueForm
to display the function definitions using Full- or InputForm? I was able to manipulate the FullForm output by converting the arguments of RuleDelayed
inside InformationValueForm
to Strings but I was not able to attach this fix to Information
or InformationValueForm
.
I do not understand the design decision behind using StandardForm in the output of Information
for user-defined functions and the whole situation is basically a bug in my opinion. The real issue are the infinite recursions and errors for more involved formatting functions which can crash the kernel and/or front-end. I tend to document my functions and I sometimes like to use Information
to remind myself of argument order. The rather unsatisfying workaround which I am currently using is to disable Information
for my formatted functions using UpValues:
CM /: Information[CM, opts___] := CM::usage;
This way I at least have access to the usage message but definitions, options and all the other Information
-data is not accessible using this workaround.
I found the answer to my question in the source code of several Mathematica core functions. Using the immensely helpful function GeneralUtilities`PrintDefinitions
on e.g. InterpolatingFunction
(or any other core function using BoxForm` ArrangeSummaryBox
for its formatted output) reveals the protected kernel function/variable BoxForm`UseIcons
. This seems to be a dynamic variable related to BoxForm
which is false for the boxes generated by Information
. The following code allows for custom formatting in the notebook but not in the output of Information
(including ?
and ??
) and other environments with BoxForm`UseIcons=False
:
MakeBoxes[..., StandartForm] /; BoxForm`UseIcons := ...
Attaching the custom formatting to MakeBoxes
instead of Format
and checking the variable BoxForm`UseIcons
does the trick and answers my question to my satisfaction. This solution is by far the better solution compared to my previous answer and the method of choice for at least some core functions with fancy formatted output. I posted a this new answer since the solution strategy differs from the previous one.
It is a pity that this is not documented alongside Format
or MakeBoxes
or even an option or default of those functions.
Correct answer by N0va on January 11, 2021
I found a somewhat feasible solution based on UpValues on the problematic user methods/symbols e.g.:
ClearAll[CM];
CM[1, a__] := CM[a]
CM /: Format[CM[a_, b__], StandardForm] := Row[{a, b}, " "]
CM /: Format[CM[a_], StandardForm] := a
Unprotect[CMinfo]; ClearAll[CMinfo];
CMinfo /: Format[CMinfo, StandardForm] = "CM";
Attributes[CMinfo] = {Protected, Constant};
CM /: Information`InformationValueForm[val_, CM, exp_List] :=
With[{s = ReleaseHold[Hold[exp] /. CM -> CMinfo]},
Information`InformationValueForm[val, CMinfo, s]]
CM /: Information`InformationValueForm[FormatValues, CM, exp_List] :=
With[{s = {Skeleton[Length[exp]]}},
Information`InformationValueForm[val, CMinfo, s]]
CM::usage = "CM::usage";
which results in the output
The symbol CMinfo
is used in ...InformationValueForm[...]
instead of CM
to prevent formatting in the definitions. The output for FormatValues
is still formatted and therefore not very informative so I inserted a placeholder instead. Maybe with a bit more work one could get the FormatValues
working as well.
This approach works well enough for me but I am still rather unpleased with the necessity for such measures. The Information[...]
method should work out of the box on valid user functions. So I am still in favor of calling the whole mess a bug but thank you to @Michael E2 for pointing out in the comments under the question that the tag 'bug' requires vetting. I did not read the tag description and used it wrong - sorry for that.
Note that both Information[CM]
and ??CM
work as intended when modifying ...InformationValueForm[...]
, which is surprsingly not the case for the fix put forward in my question (setting CM /: Information[CM] := CM::usage
).
The special input forms ?
and ??
are not only special by name but also special because they circumvent UpValues for Information
which again just sounds very unreasonable to me.
Answered by N0va on January 11, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP