8
$\begingroup$

What is the best way to convert an expression to a string in a reversible manner?

I need a toStr function so that it is always true that

ToExpression@toStr[expr] === expr

ToString is not satisfactory because it may use special, irreversible formatting. Example:

ToString[Graphics[{Circle[{0,0}]}]]
(* "-Graphics-" *)

In this case the problem is that it uses OutputForm by default. Requesting InputForm would solve this. But then consider

Format[x, InputForm] = "foo"

ToString[x, InputForm]
(* "foo" *)

x does exist as a proper expression in-memory. It can be written to disk by exporting to MX and then reliably re-imported. I am looking for the same functionality, but through strings.


Note: I am aware that there are some expressions which can't be safely cycled through a string, or even through Compress or through MathLink. An example would be

asc = <| a -> 1|>
a = 5;

asc
(* <| a -> 1|> *)

ToExpression@ToString[asc]  (* or use Uncompress@Compress[...] if you like *)
(* <| 5 -> 1 |> *)

I am not aiming to solve these types of difficulties, which are separate from my main problem.

$\endgroup$
  • $\begingroup$ Related: "How to convert arbitrary raw boxes directly into String?" $\endgroup$ – Alexey Popkov Aug 24 '16 at 12:28
  • $\begingroup$ InputForm does not actually solve this completely, as it returns "Graphics[{Circle[{0, 0}]}]" $\endgroup$ – Feyre Aug 24 '16 at 12:42
  • $\begingroup$ @Feyre That's due to Circle[] evaluating to Circle[{0,0}]. I changed the example to read Circle[{0,0}] to avoid misunderstanding. I do not need to prevent evaluation, just to cycle an expression through a string reliably. $\endgroup$ – Szabolcs Aug 24 '16 at 12:53
  • $\begingroup$ How about a cases structure, where it can evaluate to ToString[HoldForm[a]] if necessary? $\endgroup$ – Feyre Aug 24 '16 at 12:56
  • $\begingroup$ Can using "ExpressionJSON" help? For example, str=ExportString[Graphics[{Circle[{0, 0}]}], "ExpressionJSON", "Compact" -> True] then ImportString[#,"ExpressionJSON"]&@str. $\endgroup$ – chuy Aug 24 '16 at 18:06
2
$\begingroup$

This may fail in some obvious way, but it works on the example you give

toStr = ToString@*FullForm

For example with the following

testcases = {Graphics[{Circle[{0, 0}]}], Series[Sin[x], {x, 0, 3}], Integrate[f[x], x]}

I have

strs = toStr/@testcases
results = ToExpression /@ strs
testcases === results
(* True *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.