brandonbloom / fipp

Fast Idiomatic Pretty Printer for Clojure
526 stars 43 forks source link

print unreadable symbol utilizing #=(symbol ...) for *read-eval* #80

Open jleonard-r7 opened 2 years ago

jleonard-r7 commented 2 years ago

with two small tweaks, we could achieve REPL copy/paste-able output a la Python's "repr"

namely, have symbols rendered as:

[:text (str "(symbol \"" x "\")")]

and seqs rendered as:

(pretty-col this "'(" x :line ")" visit)

Any reason (besides annoyance-parity with cljs.pprint/pprint) this wasn't considered?

brandonbloom commented 2 years ago

Hey @jleonard-r7, if I understand correctly, what you're asking for here is support for round-tripping of unreadable symbols (ie those with invalid syntax, but valid runtime representations). The round-tripping pair of read and pr in Clojure don't really have an analogous pair in Python. Python's str is similar to Clojure's pr-str, but Python's repr is something like (comp pr-str uneval). That is, it's the inverse of eval, not read. This however is especially tricky and problematic for symbols, because of evaluation rules.

I think what you're really asking for here is support for printing using the semi-secret #= reader form. See *read-eval* as well. In this world, some invalid symbol would be printed like: #=(symbol "namespace with spaces in it" "and/some~invalid(chars)here").

Note that your proposed implementation has numerous problems: consider namespaces, as well as embedded slashes or quote characters in the symbol.

I'm open to the idea of detecting unreadable symbols and fallingback to #_. Maybe, maybe-not guarded by some :print-eval true option. My main concern here is that analyzing a symbol for readability may meaningfully impact performance for large data printing, which is a primary usecase of Fipp.

Given how easy it is to create a new printer (basically just copy/paste/tweak edn.cljc), I'm tempted to close this issue, but I'll leave it open in case anyone wants to attempt this and see how big the code and performance impact is.