@@ -39,41 +39,31 @@ library that uses parser of GHC itself for parsing and thus it guarantees
3939that at least parsing phase is bug-free (which is admittedly the cause of
4040majority of bugs in other projects, see below).
4141
42−`ghc-exactprint` is capable of dealing not only with vanilla Haskell source
43−code, but also with CPP. However it does so by running the preprocessor with
44−parameters provided by user (such as values of `#defines`). It doesn't parse
45−actual preprocessor directives in a way that would allow their
46−reconstruction, thus Brittany still lacks support for handling source code
47−with CPP in it. That said, we'll show later supporting CPP correctly is
48−virtually impossible anyway.
49−
50−The [theory][brittany-theory] behind Brittany is quite complex and the code
51−itself is fairly undocumented.
52−
5342After parsing, Haskell AST and a collection of annotations are available.
5443The annotations are there because Haskell AST doesn't provide enough
5544information to reconstruct source code (for example it doesn't include
56−comments). Brittany's approach then amounts to converting AST to the special
57−`BriDoc` data type which describes syntactical entities with just enough
58−details to pretty-print them. Stateful transformations are then performed on
59−that `BriDoc` type.
60−
61−Using `BriDoc` data type alone would lead to exponential time complexity
62−though and so `BriDocF` type is also added. There are multiple ways to build
63−a `BriDocF`, and only some of them meet the linear space property. Which
64−means there is no safety net to ensure that the resulting structures fit in
65−linear space. And this is a problem that certainly would require redesign to
66−overcome.
67−
68−After the manipulations a few functions from `ghc-exactprint` are used for
69−rendering of code together with some custom logic. I do not fully understand
70−why the function `exactPrint` from `ghc-exactprint` is not used directly.
71−
72−The code is hard to read and is buggy too, as one would expect with such
73−approach. There are enough bugs in Brittany at the moment so that it's
74−hardly usable although it's now 2 years old. Looking at the opened bugs it's
75−clear that almost all of them are because of the implementation and design
76−complexity.
45+comments). The AST and the annotations are converted into a `BriDoc` value.
46+A BriDoc value is a document representation like the `Doc` from the
47+[pretty][pretty-doc] or the [wl-pprint][wl-pprint-doc] libraries.
48+
49+Brittany implements its own document type in an attempt to find a
50+satisfactory rendering of the source code that fits a page-width
51+constraint. Because of this, a `BriDoc` value represents a collection
52+of many candidate layouts (i.e. renderings) of the source code.
53+
54+This collection is pruned until it contains a single layout. The
55+structure of the chosen layout is then adjusted to leave it in a
56+form which can be easily traversed to produce the final rendering.
57+
58+Brittany invests the majority of its implementation to manage
59+the `BriDoc` values. Given that the amount of possible layouts is
60+exponential, the representation is clever enough to fit them in
61+linear space. There are multiple ways to build a `BriDoc`, not all
62+of which fit in linear space. So care is necessary to keep memory
63+bounded.
64+
65+The compexities of the `BriDoc` structure together with the lack of
66+documentation, make Brittany at least challenging to maintain.
7767
7868### Hindent
7969
@@ -85,10 +75,9 @@ below). This already makes all these projects unusable with some valid
8575Haskell source code, but let's continue studying Hindent anyway.
8676
8777Hindent is quite different from Brittany in the sense that it does not
88−attempt to do manipulations on source code and annotations to print them
78+attempt to build a document representation to render
8979afterwards, instead it just prints the parsed code straight away. This means
90−that maybe 70-80% of the code does printing, the package is essentially is
91−about pretty-printing parsed Haskell code.
80+that the 70-80% of what the code does is a printing traversal.
9281
9382Perhaps surprisingly, this approach seems to be better (IMO), for several
9483reasons:
@@ -472,5 +461,6 @@ Proposed roadmap (for a single person, about 39 full-time work days):
472461[outputable]: https://hackage.haskell.org/package/ghc-8.4.3/docs/Outputable.html
473462[haskell-src-exts]: https://hackage.haskell.org/package/haskell-src-exts
474463[ghc-exactprint]: https://hackage.haskell.org/package/ghc-exactprint
475−[brittany-theory]: https://github.com/lspitzner/brittany/blob/master/doc/implementation/index.md
476464[hindent-printer]: https://github.com/commercialhaskell/hindent/blob/master/src/HIndent/Pretty.hs
465+[pretty-doc]: http://hackage.haskell.org/package/pretty-1.1.3.6/docs/Text-PrettyPrint.html#t:Doc
466+[wl-pprint-doc]: http://hackage.haskell.org/package/wl-pprint-1.2.1/docs/Text-PrettyPrint-Leijen.html#t:Doc