# TextString evaluation leak

Bug introduced in 10.4 or earlier and persisting through 11.3

[...] I checked and reproduced your issue, and have passed along a report to our developers on the same [...]

CASE:3972929

TextString@HoldForm[1/0]
TextString@Hold[1/0]


Is this behavior expected? I failed to explain this with documentation, the more that it says:

In other cases, expressions are formatted using InputForm

but:

ToString[Hold[1/0], InputForm]
ToString[HoldForm[1/0], InputForm]


The problem is the more important that TextString is a default InsertingFunction for a StringTemplate.

• I am not sure, but could it be posible that $1/0$ is interpreted by MMA as a symbol DirectedInfinity and not as an operation? – José Antonio Díaz Navas Nov 14 '17 at 18:02
• @JoséAntonioDíazNavas it could be but it is not the case because the message is issued. – Kuba Nov 15 '17 at 8:38

The case of HoldForm appears to by design, although the motivation for that design is unclear. HoldForm should thus be listed as one of the special heads listed in the TextString documentation. The case of Hold appears to be an evaluation leak, but maybe it is intentional for symmetry with HoldForm.

HoldForm Variant

A trace of the HoldForm variant suggests that the behaviour is by design. Here are selected evaluations from the trace:

The internal ostr helper function has definitions that explicitly strip HoldForm:

Needs["GeneralUtilities"]
GeneralUtilitiesTextStringPackagePrivateostr //
DownValues // Select[Not@*FreeQ[HoldForm]] // PrettyForm


The documentation for TextString lists a number of heads that are treated specially -- apparently HoldForm should be added to that list.

Hold Variant

The case of the Hold variant is not so clear. Here is a selective trace:

There are no definitions under any of the internal helper functions that explicitly deal with Hold. A close inspection of the trace yields use of Unevaluated, which suggests that some attempt was made to prevent evaluation. But this measure is defeated by later steps.

My guess is that there is an evaluation leak here, but perhaps it is just a happy(?) accident that results in a treatment for Hold that matches that of HoldForm.

Motivation?

Why would HoldForm be stripped when converting an expression to a string? I have no idea. It would seem that the ability to convert unevaluated expressions to strings would be valuable. If it weren't for the explicit definitions on ostr, I would have called this a bug. Now I guess I have to call it an inscrutable design decision.

(This analysis is current as of Mathematica 11.2.0.)