<div dir="ltr">Wow, looks very promising.</div><br><div class="gmail_quote"><div dir="ltr">сб, 5 авг. 2017 г. в 17:29, <<a href="mailto:haskell-request@haskell.org">haskell-request@haskell.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Send Haskell mailing list submissions to<br>
        <a href="mailto:haskell@haskell.org" target="_blank">haskell@haskell.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
        <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell</a><br>
or, via email, send a message with subject or body 'help' to<br>
        <a href="mailto:haskell-request@haskell.org" target="_blank">haskell-request@haskell.org</a><br>
<br>
You can reach the person managing the list at<br>
        <a href="mailto:haskell-owner@haskell.org" target="_blank">haskell-owner@haskell.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of Haskell digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
   1. [ANN] brittany - haskell source code formatting tool -<br>
      hackage release (lennart spitzner)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Fri, 4 Aug 2017 15:01:51 +0200<br>
From: lennart spitzner <<a href="mailto:hexagoxel@hexagoxel.de" target="_blank">hexagoxel@hexagoxel.de</a>><br>
To: undisclosed-recipients: ;<br>
Subject: [Haskell] [ANN] brittany - haskell source code formatting<br>
        tool - hackage release<br>
Message-ID: <<a href="mailto:14f23926-b296-865d-7eeb-1a232427fd07@hexagoxel.de" target="_blank">14f23926-b296-865d-7eeb-1a232427fd07@hexagoxel.de</a>><br>
Content-Type: text/plain; charset=utf-8<br>
<br>
Greetings,<br>
<br>
I am happy to (finally) announce the first hackage release of brittany, a<br>
configurable haskell source code formatter based on ghc-exactprint [2].<br>
<br>
<a href="https://hackage.haskell.org/package/brittany" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/brittany</a><br>
<a href="https://github.com/lspitzner/brittany" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany</a><br>
<br>
<br>
*Introduction*<br>
<br>
Brittany aims to nicely layout the code and retain empty lines and comments as<br>
they appear in the input. For that it uses a fundamentally different approach<br>
(see [7]/theory) than other formatters. The project is not finished, yet it<br>
already is usable and produces better results than other formatters in many<br>
cases. Of course these words come from its creator, so see for yourself: I<br>
have included some examples at the bottom of this mail; see [3] and [4] for<br>
some more.<br>
<br>
I wish to stress that this project will only progress at a very slow speed<br>
barring support from the community. I hereby offer to work on this and ask<br>
for funding. See the "future" paragraph below.<br>
<br>
<br>
*Changelog*<br>
<br>
Since the "alpha-release" announced previously [5] the most important changes<br>
are:<br>
<br>
- Release under the AGPL-v3;<br>
- Release on hackage;<br>
- Make horizontal alignment less aggressive by default (see example [6]);<br>
- Add high-level documentation (see [7]). This might be of interest to anyone<br>
  considering to write a formatter (haskell or even otherwise);<br>
- Improve testsuite setup;<br>
- Improve layouting in many many cases and fix various bugs;<br>
- Add a library interface (this integrates with haskell-ide-engine [8]);<br>
<br>
Brittany still..<br>
<br>
- does not touch anything other than top-level type signatures and<br>
  bindings (imports, classes, instances, data decls, .. are not modified);<br>
- contains some bugs (but it checks its own output for validity and aborts);<br>
- does not handle many "uncommon" syntactic constructs/extentions<br>
  (e.g. arrow notation);<br>
<br>
In preparation of this release the `butcher` and `czipwith` packages were<br>
published on hackage as well. I will cover those in separate announcements.<br>
<br>
<br>
*Building*<br>
<br>
Brittany currently requires ghc-8.0 (no support for previous ghc versions is<br>
planned, but 8.2 will be). Now that this package is on hackage, cabal users<br>
should be able to install it directly; stack users will currently have to clone<br>
and go from there (a stack.yaml is provided). Detailed building guides for<br>
cabal, cabal-new and stack are in the project README.<br>
<br>
Inclusion in stackage is coming as soon as all dependencies are included.<br>
<br>
<br>
*Known issues*<br>
<br>
- Bad performance for large inputs (really noticeable at >1k loc). The cause<br>
  is already determined - quadratic instead of linear complexity in one<br>
  specific function (see issue #34 [9]). Should be fixable and has high<br>
  priority.<br>
- The config (file) lacks documentation.<br>
- Comments are not always reproduced exactly when reformatting. There is a lack<br>
  of testcases for comments in the testsuite. There is the known case of<br>
  comments in List/MonadComprehensions that currently breaks idempotency (the<br>
  comments move further left each roundtrip through brittany) where a solution<br>
  will most likely involve some non-trivial changes in ghc-exactprint<br>
  (see [10]).<br>
- As mentioned above: only certain module elements are transformed, and<br>
  not all syntactical constructs are supported. re-layouting of imports, data<br>
  decls, classes and instances are on the radar, but all require a good amount<br>
  of work.<br>
- CPP is not officially supported. This is mostly a WONTFIX. One can enable it<br>
  by force, and it works to a degree, but it is relatively easy to find cases<br>
  where it will break (conditional code not being reformatted, leading to<br>
  syntax errors and theoretically also to change semantics)).<br>
- No fine-grained (per file or even per-function) control/configuration, e.g.<br>
  it is not yet possible to add some pragma/comment to disable reformatting<br>
  this one carefully layouted-by-hand function that brittany messes up.<br>
- No adaption to ghc-8.2 yet.<br>
<br>
<br>
*Future/Outlook*<br>
<br>
As far as I can tell brittany already works rather well - I use it all the<br>
time, even though I still run into issues from time to time. Still, brittany is<br>
not finished (these projects never really are, are they?).<br>
<br>
Up on my list are ghc-8.2 adaption, fixing the performance bug mentioned above,<br>
layouting of data decls, layouting of instances, and controlling<br>
behaviour/config via flags in the source (as comments).<br>
But implementing new functionality costs a lot of time, even with the DSL used<br>
internally: One has to understand the GHC AST (which is not always documented),<br>
think of all possible interactions ("do users really use record syntax when<br>
having more than one constructor?" "are GADT records a thing?"), write the<br>
layouting transformation and test it.<br>
<br>
I have already invested a good amount of my free time into this project but its<br>
scope is too large and I decided to put a limit on my personal investment.<br>
This means that barring some form of support from the community I don't see new<br>
features being implemented at any certain pace. This leaves the following<br>
paths:<br>
<br>
1) This project is supported monetarily: I hereby offer to (part-time) work on<br>
   this provided appropriate funding. I am not sure who exactly might be<br>
   interested in providing this kind of support - I am no student anymore so<br>
   GSoC is out of the question. Feel free to contact me on- or off-list if<br>
   interested.<br>
<br>
2) (More) Contributors add tests, report (and maybe fix) bugs and most<br>
   importantly implement new functionality (layouting for any syntactic<br>
   constructs of the haskell language not yet supported, etc.)<br>
<br>
   I realize that this is not a trivial project to dive into, and there is a<br>
   good amount of stuff one has to get familiar with before one can start<br>
   making use of the abstractions (the DSL) provided.<br>
<br>
   On the other hand, I _think_ that the project source code is relatively<br>
   well-structured (although in-source comments are really sparse, admittedly)<br>
   and the high-level (markdown) documentation <strike>will scare everyone<br>
   away due to their length</strike> will allow understanding the project<br>
   relatively quickly.<br>
<br>
3) The project will progress only rather slowly.<br>
<br>
Regardless I plan to continue maintaining this project, fix bugs as they come<br>
up and also work on expanding functionality when I find the time.<br>
<br>
<br>
*Contributing*<br>
<br>
In ascending order of involvement, you can contribute by:<br>
<br>
- Reporting issues, especially instances of bad layouting (especially when it<br>
  is not a pure matter of opinion);<br>
- Add to the testsuite, specifically to the `tests.blt` file of the `littests`<br>
  test. It contains a large number of tests already, but the coverage is not<br>
  very good.<br>
- If you want to really help implementing more stuff, the high-level docs [7]<br>
  are the right place to get a rough overview, especially the theory document<br>
  [11]. I have not documented how to write new layouters yet, so for now I<br>
  recommend looking at the existing ones, e.g. in `Expr.hs`.<br>
<br>
<br>
-- lennart<br>
<br>
<br>
[1] <a href="https://hackage.haskell.org/package/brittany" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/brittany</a><br>
    <a href="https://github.com/lspitzner/brittany/" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/</a><br>
[2] <a href="https://mpickering.github.io/posts/2015-07-23-ghc-exactprint.html" rel="noreferrer" target="_blank">https://mpickering.github.io/posts/2015-07-23-ghc-exactprint.html</a><br>
    <a href="https://hackage.haskell.org/package/ghc-exactprint" rel="noreferrer" target="_blank">https://hackage.haskell.org/package/ghc-exactprint</a><br>
[3] <a href="https://github.com/lspitzner/brittany/blob/da692a4341399390018fb03773e15865d967fb8c/doc/showcases/BrittanyComparison.md" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/blob/da692a4341399390018fb03773e15865d967fb8c/doc/showcases/BrittanyComparison.md</a><br>
[4] <a href="https://github.com/lspitzner/brittany/tree/master/doc/showcases" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/tree/master/doc/showcases</a><br>
[5] <a href="https://mail.haskell.org/pipermail/haskell-cafe/2016-September/124793.html" rel="noreferrer" target="_blank">https://mail.haskell.org/pipermail/haskell-cafe/2016-September/124793.html</a><br>
[6] <a href="https://github.com/lspitzner/brittany/blob/da692a4341399390018fb03773e15865d967fb8c/doc/showcases/Layout_Alignment.md#items-that-are-not-single-line-break-up-alignment" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/blob/da692a4341399390018fb03773e15865d967fb8c/doc/showcases/Layout_Alignment.md#items-that-are-not-single-line-break-up-alignment</a><br>
[7] <a href="https://github.com/lspitzner/brittany/blob/master/doc/implementation/index.md" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/blob/master/doc/implementation/index.md</a><br>
[8] <a href="https://github.com/haskell/haskell-ide-engine" rel="noreferrer" target="_blank">https://github.com/haskell/haskell-ide-engine</a><br>
[9] <a href="https://github.com/lspitzner/brittany/issues/34" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/issues/34</a><br>
[10] <a href="https://github.com/alanz/ghc-exactprint/issues/53" rel="noreferrer" target="_blank">https://github.com/alanz/ghc-exactprint/issues/53</a><br>
[11] <a href="https://github.com/lspitzner/brittany/blob/master/doc/implementation/theory.md" rel="noreferrer" target="_blank">https://github.com/lspitzner/brittany/blob/master/doc/implementation/theory.md</a><br>
<br>
<br>
--<br>
<br>
some layouting examples - would be (re)produced in exactly this way by<br>
brittany:<br>
<br>
> main = do<br>
><br>
>   now <- getCurrentTime<br>
>   let (_, _, week) = toWeekDate . utctDay $ now<br>
>   putStrLn $ ("it's "++) $ case week of<br>
>     6 -> "the weekend"<br>
>     7 -> "the weekend"<br>
>     _ -> "a weekday"<br>
><br>
>   localtime <- utcToLocalZonedTime now<br>
>   let hr = todHour . localTimeOfDay . zonedTimeToLocalTime $ localtime<br>
>   case hr of<br>
>     _ | hr < 12   -> putStrLn "it's before noon"<br>
>       | otherwise -> putStrLn "it's after noon"<br>
<br>
> -- Newlines are used sparingly: Only after "do" and when the<br>
> -- `liftBaseOpDiscard` application would lead to overflowing 80 columns.<br>
> main :: IO ()<br>
> main = do<br>
>   pool <- createPostgresqlPool (toS databaseConnectionString) 10<br>
>   initiate $ \chan -> forever $ do<br>
>     flip runDbConn pool $ do<br>
>       makeSureQueueIsFull chan<br>
>       void $ liftBaseOpDiscard (consumeMsgs chan responseQueue Ack)<br>
>                                (uncurry processMsg)<br>
>     threadDelay 1000000<br>
<br>
> -- Alignment of patterns<br>
> go []                 ""     = True<br>
> go [WildCard        ] ""     = True<br>
> go (WildCard   :rest) (c:cs) = go rest (c : cs) || go (WildCard : rest) cs<br>
> go (Union globs:rest) cs     = any (\glob -> go (glob ++ rest) cs) globs<br>
> go []                 (_:_)  = False<br>
> go (_:_)              ""     = False<br>
<br>
<br>
<br>
<br>
------------------------------<br>
<br>
Subject: Digest Footer<br>
<br>
_______________________________________________<br>
Haskell mailing list<br>
<a href="mailto:Haskell@haskell.org" target="_blank">Haskell@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell</a><br>
<br>
<br>
------------------------------<br>
<br>
End of Haskell Digest, Vol 168, Issue 3<br>
***************************************<br>
</blockquote></div>