<div dir="ltr"><div><div>Thanks Ben, a great summary.  Is there a Wiki page for this? It feels like it should be on one, so we can easily comment/update the individual points.<br><br></div>In terms of the pretty-printer and its string type. Perhaps we could backpackify it to use <a href="http://next.hackage.haskell.org:8080/package/str-sig">http://next.hackage.haskell.org:8080/package/str-sig</a>, and then specialise the GHC version to FastString etc.<br><br></div>Alan<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 3 June 2017 at 17:50, Ben Gamari <span dir="ltr"><<a href="mailto:ben@smart-cactus.org" target="_blank">ben@smart-cactus.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
CCing,<br>
   * Alfredo Di Napoli for his on-going work in this area<br>
   * Shivansh Rai for his interest in contributing<br>
   * David Luposchainsky for his recent pretty-printer library<br>
   * Richard Eisenberg due to his participation in #8809<br>
   * Bartosz for his participation in #10735<br>
   * Alan Zimmerman for his interest in Haskell tooling<br>
<br>
My apologies for the tome that follows. I have been thinking about this<br>
problem recently and think an overview of where we stand would be helpful.<br>
<span class=""><br>
<br>
Siddharth Bhat <<a href="mailto:siddu.druid@gmail.com">siddu.druid@gmail.com</a>> writes:<br>
<br>
> Hello all,<br>
><br>
> Thanks for all the work that's put into GHC :)<br>
><br>
</span>Thanks for your interest in helping!<br>
<span class=""><br>
> I've tried to get into GHC development before, but I was unsuccessful,<br>
> mostly because I didn't dedicate enough time to understanding the problem<br>
> at hand & exploring the codebase.<br>
><br>
> I'd like to give it another shot. This time, I think I have a clear vision<br>
> of what I want to help with: Have haskell's error messages be easier to<br>
> read and understand.<br>
><br>
> 1. Colors and layout to highlight important parts of the error messages<br>
<br>
</span>As I say below, I think #8809 will provide a good foundation for<br>
improvements here. More on this below.<br>
<span class=""><br>
> 2. Clear formatting & naming of errors, so they're easily googleable,<br>
> stack-overflow able, etc.<br>
<br>
</span>Indeed this is a great goal. Do you have a list of error messages that<br>
you think are particularly egregious in this respect? Are you advocating<br>
that we give error classes unique identifiers (e.g. as rustc does IIRC)<br>
or are you merely suggesting that we improve the wording of the existing<br>
messages?<br>
<span class=""><br>
> 3. better hints with error messages, and perhaps integrated lints(?).<br>
<br>
</span>This sounds like a noble goal, but it's a bit unclear how you get there.<br>
We currently do try to give hints where possible, but of course we could<br>
always offer more. It would be helpful to have a set of concrete<br>
examples to discuss.<br>
<span class=""><br>
> 4. I don't know if this is already possible, but allowing GHC errors to be<br>
> shipped off as JSON or something to interested tooling.<br>
><br>
</span>Indeed, this would be great. Thanks to Matthew Pickering we already<br>
offer some limited form of this in 8.2 [1], but I think having more<br>
structured error documents as suggested in #8809 would make this even<br>
nicer.<br>
<br>
[1] <a href="https://downloads.haskell.org/~ghc/master/users-guide//debugging.html?highlight=json#ghc-flag--ddump-json" rel="noreferrer" target="_blank">https://downloads.haskell.org/<wbr>~ghc/master/users-guide//<wbr>debugging.html?highlight=json#<wbr>ghc-flag--ddump-json</a><br>
<br>
<br>
<br>
The State of #8809<br>
==================<br>
<span class=""><br>
> I saw this ticket on trac: <a href="https://ghc.haskell.org/trac/ghc/ticket/8809" rel="noreferrer" target="_blank">https://ghc.haskell.org/trac/<wbr>ghc/ticket/8809</a><br>
> I would like to take this up, but I'd like help / pointers and stuff. I<br>
> have GHC setup, I know how to use phabricator, but.. where do I start? :)<br>
><br>
</span>This ticket has recently seen quite a bit of activity and I've been<br>
meaning to write down some thoughts on it. Here it goes:<br>
<br>
Currently Alfredo Di Napoli is working [2] on the `pretty` library to<br>
both improve performance and allow us to drop GHC's fork (see #10735),<br>
perhaps to use annotated pretty-printer documents. Meanwhile, David<br>
Luposchainsky, has recently released [3] his `prettyprinter` library<br>
which may serve as a drop-in replacement to `pretty` and handles all of<br>
the cases that Alfredo is working on. Moreover, Shivansh Rai has also<br>
recently expressed interest in helping out with this effort.<br>
<br>
All of this is great news: I have been hoping we'd get Idris-style<br>
errors for quite some time. However, given how many hands we have in<br>
this area, we should be careful not to step on each toes. Below I'll<br>
describe the various facets of the task as I see them.<br>
<br>
[2] <a href="https://github.com/haskell/pretty/pull/43" rel="noreferrer" target="_blank">https://github.com/haskell/<wbr>pretty/pull/43</a><br>
[3] <a href="https://www.reddit.com/r/haskell/comments/6e62i5/ann_prettyprinter_10_ending_the_wadlerleijen_zoo/" rel="noreferrer" target="_blank">https://www.reddit.com/r/<wbr>haskell/comments/6e62i5/ann_<wbr>prettyprinter_10_ending_the_<wbr>wadlerleijen_zoo/</a><br>
<br>
<br>
# Choice of pretty printer<br>
<br>
It seems like we first need to resolve the question of whether switching<br>
from (our fork of) `pretty` to the `prettyprinter` library is<br>
worthwhile. The argument for moving to `prettyprinter` is its support<br>
for optimized infinite-band-width layout, which is one of the things<br>
holding us back from moving back to `pretty`.<br>
<br>
However, there are two impediments to switching,<br>
<br>
 * `prettyprinter` depends upon the `text` package while GHC does not.<br>
   Making GHC dependent on `text` is an option, but we should be<br>
   careful. Adding a dependency has a non-trivial cost (GHC build times<br>
   rise, GHC API users are stuck using whatever dependency versions GHC<br>
   uses, release engineering is a bit more complicated).<br>
<br>
   Currently GHC has its own abstractions for working with text<br>
   efficiently, LitString and FastString. FastString is used throughout<br>
   the compiler, including the pretty-printer, and represents a<br>
   dense UTF-8 buffer (and a hash for quick comparison). It's not clear that we<br>
   would want to move it to `text` as this would introduce UTF-8/UTF-16<br>
   conversion.<br>
<br>
 * `prettyprinter` doesn't support rendering to `String`. This<br>
   essentially means that we either use `Text` or fork the package.<br>
   However, if we have already decided on depending on `text`, then<br>
   perhaps the former isn't so bad.<br>
<br>
It's unclear to me exactly how difficult switching would be compared to<br>
finishing up the work Alfredo has started on `pretty`. Alfredo, what is<br>
your opinion?<br>
<br>
If we decide against moving to `prettyprinter`, then we will need to<br>
finish up something like Alfredo's `pretty` patches to rid GHC of its<br>
fork.<br>
<br>
<br>
# Representing rich error messages in GHC<br>
<br>
In my opinion we should avoid baking more stylistic decisions (e.g. printing<br>
types in red, terms in blue) into the modules like TcErrors which produce<br>
error messages. This is why I propose that we use annotated<br>
pretty-printer documents in #8809 (see comment 3). This would allow us<br>
to represent the typical things seen in GHC error messages (e.g. types,<br>
terms, spans, binders, etc.) in structured form, allowing the error<br>
message consumer (e.g. GHC itself, a GHC API user, or some JSON error<br>
sink) to make decisions about how to present these elements to the user.<br>
<br>
I think this approach give us a much better story for dealing with the<br>
problems currently solved by flags like -fprint-runtime-reps,<br>
-fprint-explicit-kinds, etc., especially for users using an IDE.<br>
<br>
As far as I can recall, there was still a bit of disagreement<br>
surrounding whether the values carried by the error message should be<br>
statically or dynamically typed. In particular, Richard Eisenberg<br>
advocated that error message documents look like,<br>
<br>
    -- A dynamically typed value embedded in an error message<br>
    data ErrItem = forall a. (Outputable a, Typeable a). ErrItem a<br>
<br>
    type ErrDoc = Doc ErrItem<br>
<br>
Whereas I argue that this would quickly become unmaintainable,<br>
especially when one considers GHC API users. Rather, I say that we<br>
should encode the "vocabulary" of things that may appear in an error<br>
message explicitly,<br>
<br>
    data ErrItem = ErrType Type<br>
                 | ErrSpan Span<br>
                 | ErrTerm HsExpr<br>
                 | ErrInstance ClsInst<br>
                 | ErrVar  Var<br>
                 | ...<br>
<br>
While there are good arguments for both options, although I think that<br>
in balance an explicit approach will be better for consumers. Anyways,<br>
this is a question that will need to be answered.<br>
<br>
Once there is consensus I think it shouldn't be too difficult to move<br>
things forward. The change can be made incrementally and for the most<br>
part should only touch a few modules (with the bulk in TcErrors).<br>
<br>
<br>
## What do we represent?<br>
<br>
There is also the question of what the vocabulary of embeddable items<br>
should consist of. I think the above are pretty non-controversial but I<br>
can think of a variety of items which would more precisely capture<br>
some common patterns,<br>
<br>
    data ErrItem = ...<br>
                 | ErrExpectedActual Type Type<br>
                   -- ^ e.g. "Expected type: ty1, Actual type: ty2"<br>
                 | ErrContext Type<br>
                   -- ^ Like ErrType but specifically captures a context<br>
                 | ErrPotentialInstances [ClsInst]<br>
                   -- ^ A list of potentially matching instances<br>
                 | ...<br>
<br>
Exactly how far we want to go is something that would need to be<br>
decided. I think we would want to start with the minimal set initially<br>
proposed and then introduce additional items as we gain experience with<br>
the scheme.<br>
<br>
<br>
# Using rich error messages<br>
<br>
Once we have GHC producing rich error documents we can teach GHC's<br>
command line driver to prettify them. We can also teach haskell-mode,<br>
ghc-mod, and friends to preserve their structure to give the user an<br>
Idris-like experience.<br>
<br>
Exactly how many stylistic decisions we want GHC to make is a tricky<br>
question; this is prime territory for bike-shedding and people tend to<br>
have rather strong aesthetic beliefs; keeping things simple while<br>
satisfying all tastes may be a challenge.<br>
<br>
<br>
# Summary<br>
<br>
Above I discussed several tasks and a few questions,<br>
<br>
 * We need to decide on whether David's `prettyprinter` library is right<br>
   for GHC; having a prototype patch introducing it to the tree would<br>
   help in evaluating this. Alfredo, what is your opinion here?<br>
<br>
 * If not we need to drop our fork of `pretty` in favor of upstream<br>
<br>
 * We need consensus on whether Idris-style annotated pretty-printer<br>
   documents are the right approach for GHC (I think we are close to<br>
   this)<br>
<br>
 * If we want annotated documents, should the items be statically or<br>
   dynamically typed?<br>
<br>
 * Once these questions are resolved we can start introducing<br>
   annotations into GHC's error documents (this shouldn't be hard)<br>
<br>
 * Then we can teach GHC and associated tooling to pretty-print these<br>
   rich messages prettily<br>
<br>
There is certainly a fair bit of work here although it's not<br>
obvious how to parallelize it across all of the interested<br>
parties. Regardless, I would be happy to advise on any bit of this.<br>
<br>
Cheers,<br>
<br>
- Ben<br>
<br>
<br>
</blockquote></div><br></div>