HoldForm
holds an expression's parsed form not its actual "inputted form" e.g.
SetAttributes[AttemptedRespect, HoldAll];
AttemptedRespect[x_] := ExpressionCell[HoldForm@x, "Input"]
(assoc = <|f@x -> (x // g)|>) // AttemptedRespect
assoc = Association[f[x] -> g[x]]
where the held short forms/notation of Association
/f
/g
are no longer respected.
To instigate respect:
FleetingRespect[expr_] :=
(Unprotect@Association;
Format[Association[x__]] := <|x|>;
Format[f[x_]] := Prefix[f@x];
Format[g[x_]] := Postfix[x // g];
ExpressionCell[HoldForm@expr, "Input"])
and:
(assoc = <|f@x -> (x // g)|>) // FleetingRespect
assoc = <|f@x -> (x // g)|>
which is, of course, indeed fleeting:
(assoc = Association[(x // f) -> (g@x)]) // FleetingRespect
assoc = <|f@x -> (x // g)|>
Is there a way to cajole HoldForm
into more faithfully respecting what she wraps?
In other words - a function PermanentRespect
such that:
(assoc = <|f@x -> (x // g)|>) // PermanentRespect
assoc = <|f@x -> (x // g)|>
and
(assoc = Association[(x // f) -> (g@x)]) // PermanentRespect
assoc = Association[(x // f) -> (g@x)]
Yoh - Respect.
Answer: The final effort in Simon Rochester's answer almost creates a pre-parsed HoldForm
(without touching $PreRead
) and it certainly meets the use-case requirements that originally motivated the question. Essentially I wanted to programmatically generate the "natural input shortforms" with normal output form (without using any frontend manipulations).
MakeExpression[
RowBox@{"hf", "[", expr_, "]"} |
RowBox@{"hf", "@", expr_} |
RowBox@{expr_, "//", "hf"}, StandardForm] := HoldComplete@RawBoxes@expr;
SetAttributes[IOCells, HoldAll];
IOCells[expr_] := Grid[{
{ExpressionCell[expr, "Input", ShowStringCharacters -> True]},
{ExpressionCell[ToExpression@First@expr, "Output"]}},
Frame -> True,
Alignment -> Left,
Background -> {None, {1 -> GrayLevel[.9], 2 -> White}}];
and now both examples
Grid[{
{hf[assoc = <|f@x -> (x // g)|>],
hf[assoc = Association[(x // f) -> (g@x)]]}
}] // (Map[IOCells, #, {3}] &)
preserve input forms, respectively.
PermanentRespect
should also not have lingering side affects. e.g.FleetingRespect
pollutes the name space while ensuring thatAssociation
formats with <| |> has unexpected consequences (e.g.AssociationMap[f]@<|a->1|>
goes into infinite recursion ) $\endgroup$PreRead
,RawBoxes
etc seems unavoidable although in this use case this seems disproportionate, unjustified spelunking. Functions likeInactivate
/Activate
perhaps suggest new attention to formatting of Input forms which made me wonder if aPermanentRespect
is implementable at a higher level. $\endgroup$