Add more high-level documentation: index, dataflow
parent
eac73c9a7b
commit
d56c4f5e6b
|
@ -103,7 +103,6 @@ stack build
|
|||
- -XBangPatterns
|
||||
~~~~
|
||||
|
||||
# Implementation
|
||||
# Implementation/High-level Documentation
|
||||
|
||||
I have started adding documentation about the main data type `BriDoc`; see the
|
||||
"docs/implementation" folder. Start with "bridoc-design.md".
|
||||
[See the documentation index](docs/implementation/index.md)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
# Dataflow
|
||||
|
||||
From the program design standpoint, Brittany performes a
|
||||
`Config -> Text -> Text` transformation; it is not interactive in any way and
|
||||
it processes the whole input at once (no streaming going on). This makes for
|
||||
a very simple design with nice separation of IO and non-IO.
|
||||
|
||||
Brittany makes heavy usage of mtl-on-steroids-style transformers, mostly
|
||||
limited to Reader, Writer and State. For this kind of task it makes a lot of
|
||||
sense; we do a pure transformation involving multiple steps
|
||||
that each requires certain local state during traversals of recursive data
|
||||
structures. By using MultiRWS we can avoid using lens for the most part without
|
||||
inducing too much boilerplate.
|
||||
|
||||
Firstly, the topmost layer, the IO bits:
|
||||
|
||||
<img src="https://cdn.rawgit.com/lspitzner/brittany/7775812cfdc7d2596883f87b5ba9207fbf61f2b3/doc-svg-gen/generated/periphery.svg">
|
||||
|
||||
The corresponding code is in these modules:
|
||||
|
||||
- `Main`
|
||||
- `Language.Haskell.Brittany`
|
||||
|
||||
The latter [contains the code to run our Reader/Writer/State stack](https://github.com/lspitzner/brittany/blob/7775812cfdc7d2596883f87b5ba9207fbf61f2b3/src/Language/Haskell/Brittany.hs#L64-L75) (well, no state yet).
|
||||
|
||||
Note that `MultiRWS` here behaves like a nicer version of a stack like
|
||||
`ReaderT x (ReaderT y (WriterT w1 (WriterT2 w2 (Writer w3)..)`.
|
||||
The next graph zooms in on that transformation:
|
||||
|
||||
<img src="https://cdn.rawgit.com/lspitzner/brittany/7775812cfdc7d2596883f87b5ba9207fbf61f2b3/doc-svg-gen/generated/ppm.svg">
|
||||
|
||||
Two places (The `BriDoc` generation and the backend) have additional local
|
||||
state (added to the monadic context).
|
||||
The following is a very simplified description of the BriDoc generation:
|
||||
|
||||
<img src="https://cdn.rawgit.com/lspitzner/brittany/7775812cfdc7d2596883f87b5ba9207fbf61f2b3/doc-svg-gen/generated/bridocgen.svg">
|
||||
|
||||
|
||||
For the `BriDoc` generation, the relevant modules are
|
||||
- `Language.Haskell.Brittany.Layouters.*`
|
||||
- `Language.Haskell.Brittany.LayouterBasics`
|
||||
|
||||
For the `BriDoc` tree transformations, the relevant modules are
|
||||
- `Language.Haskell.Brittany.Transformations.*`
|
||||
|
||||
Finally, for the backend, the relevant modules are
|
||||
- `Language.Haskell.Brittany.Backend`
|
||||
- `Language.Haskell.Brittany.BackendUtils`
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
- [theory](theory.md)
|
||||
|
||||
Explains the core idea of the formatter that makes it so cool.
|
||||
|
||||
- [dataflow](dataflow.md)
|
||||
|
||||
Looking at how the data is tranformed should give the reader a good
|
||||
idea of the high-level design, given that Brittany essentially
|
||||
performs a `Text -> Text` transformation.
|
||||
|
||||
- [bridoc-design](bridoc-design.md)
|
||||
|
||||
An explanation of the `BriDoc` datatype focussed on (potential) contributors
|
||||
that wish to add support for more syntactical constructs.
|
||||
|
||||
- [bridoc-api](bridoc-api.md)
|
||||
|
||||
Specifying the semantics of the different (smart) constructors of the
|
||||
`BriDoc` type.
|
||||
|
||||
- Brittany uses the following (randomly deemed noteworthy) libraries:
|
||||
|
||||
- [`ghc-exactprint`](https://hackage.haskell.org/package/ghc-exactprint)
|
||||
(and [`ghc`](https://hackage.haskell.org/package/ghc)) for parsing of haskell source;
|
||||
- [`uniplate`](https://hackage.haskell.org/package/uniplate)
|
||||
for efficient transformations on the recursive `BriDoc` datatype;
|
||||
this powers the main computational work done by Brittany;
|
||||
- [`monad-memo`](https://hackage.haskell.org/package/monad-memo)
|
||||
for explicit function memoization;
|
||||
- [`multistate`](https://hackage.haskell.org/package/multistate)
|
||||
as an alternative to an unwieldly transformer stack;
|
||||
- [`butcher`](https://github.com/lspitzner/butcher)
|
||||
for parsing commandline arguments (as an alternative to
|
||||
[`optparse-applicative`](https://hackage.haskell.org/package/optparse-applicative))
|
||||
- [`yaml`](https://hackage.haskell.org/package/yaml)
|
||||
to handle config file;
|
||||
- [`safe`](https://hackage.haskell.org/package/safe)
|
||||
and
|
||||
[`unsafe`](https://hackage.haskell.org/package/unsafe)
|
||||
(heh).
|
||||
|
|
@ -9,8 +9,9 @@ project, including the following two:
|
|||
|
||||
These two goals stand in conflict, and this project chooses a solution
|
||||
to this that distinguishes it from (all) other existing formatters. This
|
||||
idea was the motivation to write Brittany in the first place, and it might
|
||||
even be applicable to more general-purposes structured-document formatters
|
||||
approach was an important motivation for writing Brittany, when other
|
||||
formatters already existed. The approach might
|
||||
also be applicable to more general-purposes structured-document formatters
|
||||
(although we will not expand on that here). Before explaining the idea, we
|
||||
will first consider
|
||||
|
||||
|
@ -55,8 +56,8 @@ same expression:
|
|||
|
||||
~~~~.hs
|
||||
-- 10 20 30 40
|
||||
-- 1) -- | lets assume the user wants
|
||||
nestedCaseExpr = case e1 of -- | 40 columns max.
|
||||
-- 1) -- lets assume the user wants
|
||||
nestedCaseExpr = case e1 of -- 40 columns max.
|
||||
Left x -> if func x then "good" else "bad" -- too long
|
||||
-- 2) --
|
||||
nestedCaseExpr = case e1 of --
|
||||
|
@ -193,9 +194,10 @@ required per node of the input.
|
|||
this to the `nestedCaseExpr` example above: The options are to either
|
||||
put the right-hand-side of the case-alternative into a new line, or
|
||||
split up the if-then-else. The "case" is the outer one, so Brittany will
|
||||
prefer 3) over 2), which proves to be the right choice (here).
|
||||
prefer 3) over 2), which proves to be the right choice (at least in this
|
||||
case).
|
||||
|
||||
As a consequence, we are most interested in the maximum spacings; yet, we do
|
||||
As a consequence, we are most interested in the maximum spacings. Still we do
|
||||
not have a total order because we cannot generally prefer one of two spacings
|
||||
where the first uses more columns, the second more lines.
|
||||
|
||||
|
|
Loading…
Reference in New Issue