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$
5
  • $\begingroup$ Related: "How to convert arbitrary raw boxes directly into String?" $\endgroup$ Commented Aug 24, 2016 at 12:28
  • $\begingroup$ InputForm does not actually solve this completely, as it returns "Graphics[{Circle[{0, 0}]}]" $\endgroup$
    – Feyre
    Commented Aug 24, 2016 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
    Commented Aug 24, 2016 at 12:53
  • $\begingroup$ How about a cases structure, where it can evaluate to ToString[HoldForm[a]] if necessary? $\endgroup$
    – Feyre
    Commented Aug 24, 2016 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
    Commented Aug 24, 2016 at 18:06

1 Answer 1

3
$\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 and acknowledge you have read our privacy policy.

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