
Hi all! A few months ago I proposed to change the escaping behavior of `show`. The general consensus is that it will introduce hard-to-find and unpredictable amount of breakage. However, I still think there should be a standard (i.e. living in base) solution to that problem. Instead of changing existing instances, we can add new functions. Therefore, I propose: 1. Add `showNE` [1] to `Show`, with a default implementation `showNE = show`. 2. Add `printNE x = putStrLn (showNE x)`. 3. Change ghci’s default print function to `printNE`. 4. Document that `show` escapes strings so its output will support ASCII terminals, where `showNE` is limited to only terminals that support Unicode. This proposal benefits ghci without breaking any existing code, and the older behavior can be restored by `:set -interactive-print print`. Q&A: - Why not just use existing packages, like pretty-simple, for this purpose? I believe ghci should support this behavior (non-escaping) out of box without installing any third-party packages. - Why not just add `printNE` which undoes escaping? Definitely doable. However, it feels more like a hack than a solution. According to the new CLC process, this proposal should be submitted to https://github.com/haskell/core-libraries-committee/issues. But I’d like to hear some early feedback, and I will implement this proposal. [1] “NE” stands for non-escaping. This is only a temporary name in order to avoid bike-shedding. Regards, Kai

Hello Kai, Il 19 dicembre 2021 alle 17:53 Kai Ma ha scritto:
This proposal benefits ghci without breaking any existing code, and the older behavior can be restored by `:set -interactive-print print`.
Just to check if I understood correctly: only ghci will benefit from this proposal, right? Are there other place where printNE/showNE could be useful? Why not a new typeclass instead of modifying the venerable `Show`?

Hello Francesco,
Just to check if I understood correctly: only ghci will benefit from this proposal, right? Are there other place where printNE/showNE could be useful?
The motivation is to enhance the experience of ghci, but IMO there are a few other places it can be useful. Off the top of my head are: 1. Some development tools, like IHP’s tool, can use `showNE` in place of `show` to directly output Unicode strings. 2. At least Text (and perhaps ByteString) can make use of `showNE`.
Why not a new typeclass instead of modifying the venerable `Show`?
People are deriving Show for their types today, so adding methods to Show is a non-intrusive and backward-compatible way to update old code smoothly. Of course, an alternative way is to make GHC derive two instances simultaneously, for Show and for (say) ShowNE, but I’m not entirely sure whether it’s good practice. I agree adding a new class is better if deriving two instances is allowed. Kai

I would be very interested to integrate this in my text-display¹ library! ¹ https://github.com/haskell-text/text-display Le 19/12/2021 à 15:38, Kai Ma a écrit :
Hello Francesco,
Just to check if I understood correctly: only ghci will benefit from this proposal, right? Are there other place where printNE/showNE could be useful? The motivation is to enhance the experience of ghci, but IMO there are a few other places it can be useful. Off the top of my head are:
1. Some development tools, like IHP’s tool, can use `showNE` in place of `show` to directly output Unicode strings. 2. At least Text (and perhaps ByteString) can make use of `showNE`.
Why not a new typeclass instead of modifying the venerable `Show`?
People are deriving Show for their types today, so adding methods to Show is a non-intrusive and backward-compatible way to update old code smoothly.
Of course, an alternative way is to make GHC derive two instances simultaneously, for Show and for (say) ShowNE, but I’m not entirely sure whether it’s good practice. I agree adding a new class is better if deriving two instances is allowed.
Kai _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW: https://glitchbra.in RUN: BSD

I have opened an issue here [1], with modifications based on my experience of implementation. [1] https://github.com/haskell/core-libraries-committee/issues/25 Kai

I have some concerns that this is not as general as it could be and that it
is more invasive than one might think to "do this right."
e.g. One usecase where custom Show instances are often written is to take a
record type and transform it into something that shows with just a
positional constructor. This typically delegates to the existing showsPrec
of the fields.
I'd kind of expect "showNE" to do something sensible for such a record, but
here it'll get delegated away by default to the normal implementation,
which will delegate to showsPrec not something that tries to preserve this
property for its part.
You could move to using a 'showsPrecNE' instead of 'showNE' to enable you
to walk down to those leaf level strings you want to escape, but now
anything with a non-trivial Show instance is going to require two copies of
that non-trivial showsPrec code to be put in place.
Without something like that, as written, this proposal would make it so you
get very different output for "some unicode string" and ("some unicode
string","some other unicode string"), which seems less than optimal.
On the other hand, duplicating all the work in custom Show instances also
seems suboptimal.
I don't have a solution that I like, though several options present
themselves, but I did want to throw up this concern before folks ran away
and pushed this into base.
-Edward
On Sun, Dec 19, 2021 at 11:26 PM Kai Ma
I have opened an issue here [1], with modifications based on my experience of implementation.
[1] https://github.com/haskell/core-libraries-committee/issues/25
Kai _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (4)
-
Edward Kmett
-
Francesco Ariis
-
Hécate
-
Kai Ma