Option to value consistent layouting over minimal line count #54

Open
opened 2017-09-19 03:24:37 +02:00 by Pitometsu · 12 comments
Pitometsu commented 2017-09-19 03:24:37 +02:00 (Migrated from github.com)
data General =
  General
    { suspended    :: Maybe UTCTime
   , text1 :: Text
     , text2 :: Text
    , word :: Word
    }

e.g. hindent make it like:

data General = General
  { suspended :: Maybe UTCTime
  , text1 :: Text
  , text2 :: Text
  , word :: Word
  }

and stylish-haskell only:

data General =
  General
    { suspended :: Maybe UTCTime
   , text1      :: Text
     , text2    :: Text
    , word      :: Word
    }

But brittany just do nothing unless boilerplate take more than 80 chars in string.

```hs data General = General { suspended :: Maybe UTCTime , text1 :: Text , text2 :: Text , word :: Word } ``` e.g. `hindent` make it like: ```hs data General = General { suspended :: Maybe UTCTime , text1 :: Text , text2 :: Text , word :: Word } ``` and `stylish-haskell` only: ```hs data General = General { suspended :: Maybe UTCTime , text1 :: Text , text2 :: Text , word :: Word } ``` But `brittany` just do nothing unless boilerplate take more than 80 chars in string.
lspitzner commented 2017-09-19 22:06:41 +02:00 (Migrated from github.com)

I don't understand what you mean by

But brittany just do nothing unless boilerplate take more than 80 chars in string.

But this seems to be a duplicate of #12. Please complain if I misunderstand.

I don't understand what you mean by > But brittany just do nothing unless boilerplate take more than 80 chars in string. But this seems to be a duplicate of #12. Please complain if I misunderstand.
Pitometsu commented 2017-09-19 22:59:03 +02:00 (Migrated from github.com)

@lspitzner I just curious about ability to re-format all the lines, even short ones – to get sources formatted same way (not just re-fill long lines). I found similar ability in hindent, it even able fix some minor indentation problems. But brittany have much nicer output, so it would by pretty handy to have such functionality (e.g. to indent-region in text editor, or re-format file on save at least).

@lspitzner I just curious about ability to re-format all the lines, even short ones – to get sources formatted same way (not just re-fill long lines). I found similar ability in `hindent`, it even able fix some minor indentation problems. But `brittany` have much nicer output, so it would by pretty handy to have such functionality (e.g. to `indent-region` in text editor, or re-format file on save at least).
lspitzner commented 2017-09-19 23:20:11 +02:00 (Migrated from github.com)

Ah, using data declaration as an example confused me, as brittany does not reformat data decls in any way (yet).

Could you provide other example(s) where you dislike the current output of both brittany and hindent, or perhaps where structurally similar stuff is not formatted in the same way by brittany? (I admit that such cases probably exist, but I need to know what exactly you mean.)

Ah, using data declaration as an example confused me, as `brittany` does not reformat data decls in any way (yet). Could you provide other example(s) where you dislike the current output of both `brittany` and `hindent`, or perhaps where structurally similar stuff is not formatted in the same way by `brittany`? (I admit that such cases probably exist, but I need to know what exactly you mean.)
Pitometsu commented 2017-09-20 16:15:52 +02:00 (Migrated from github.com)

Oh, missed that brittany does not do anything with data declarations yet. Sorry, looks like lazy behaviour is common for source code formatting for all of such tools. However, it still would be very useful to have option to force brittany to be more aggressive with re-indentation and newline insertion on short lines too.

Oh, missed that brittany does not do anything with data declarations yet. Sorry, looks like lazy behaviour is common for source code formatting for all of such tools. However, it still would be very useful to have option to force brittany to be more aggressive with re-indentation and newline insertion on short lines too.
lspitzner commented 2017-09-20 17:14:18 +02:00 (Migrated from github.com)

to be more aggressive with re-indentation and newline insertion on short lines too

any examples?

> to be more aggressive with re-indentation and newline insertion on short lines too any examples?
Pitometsu commented 2017-09-20 17:39:04 +02:00 (Migrated from github.com)
realmUnprotected :: LumperConfig -> CookieSettings -> Some Other Type -> JWTSettings -> Server APIv1UnProtected

currently becomes

realmUnprotected
  :: LumperConfig
  -> CookieSettings
  -> Some Other Type
  -> JWTSettings
  -> Server APIv1UnProtected

But shorter one

realmUnprotected :: LumperConfig -> CookieSettings -> JWTSettings -> Server APIv1UnProtected

becomes ugly

realmUnprotected
  :: LumperConfig -> CookieSettings -> JWTSettings -> Server APIv1UnProtected

Furthermore, very short

realmUnprotected :: LumperConfig -> JWTSettings -> Server APIv1UnProtected

it just leave as is.


Desired behaviour: have option to format all the same way as long lines.

``` realmUnprotected :: LumperConfig -> CookieSettings -> Some Other Type -> JWTSettings -> Server APIv1UnProtected ``` currently becomes ``` realmUnprotected :: LumperConfig -> CookieSettings -> Some Other Type -> JWTSettings -> Server APIv1UnProtected ``` But shorter one ``` realmUnprotected :: LumperConfig -> CookieSettings -> JWTSettings -> Server APIv1UnProtected ``` becomes ugly ``` realmUnprotected :: LumperConfig -> CookieSettings -> JWTSettings -> Server APIv1UnProtected ``` Furthermore, very short ``` realmUnprotected :: LumperConfig -> JWTSettings -> Server APIv1UnProtected ``` it just leave as is. *** Desired behaviour: have option to format all the same way as long lines.
lspitzner commented 2017-09-20 20:55:52 +02:00 (Migrated from github.com)

Desired behaviour: have option to format all the same way as long lines.

You mean "as short lines", right? The only consistent layout here that would not violate 80 columns would be the

foo
  :: arg
  -> out

one, right?

For other cases, this might result in a lot of newlines though; I might have to decide this on a case-by-case basis. In general, brittany tries to "pay" with a low amount of newlines for the goal of remaining in 80 columns, and you want to pay some more newlines for the sake of consistency. But it might be hard to balance / hard to decide at which point this price becomes too high.

But for your example at least the price seems reasonable, and it makes sense to support such behaviour behind a flag.

> Desired behaviour: have option to format all the same way as long lines. You mean "as short lines", right? The only consistent layout here that would not violate 80 columns would be the ~~~~.hs foo :: arg -> out ~~~~ one, right? For other cases, this might result in a lot of newlines though; I might have to decide this on a case-by-case basis. In general, brittany tries to "pay" with a low amount of newlines for the goal of remaining in 80 columns, and you want to pay some more newlines for the sake of consistency. But it might be hard to balance / hard to decide at which point this price becomes too high. But for your example at least the price seems reasonable, and it makes sense to support such behaviour behind a flag.
lspitzner commented 2017-09-20 21:03:38 +02:00 (Migrated from github.com)

An example where imo the price of consistency would be too high is function application: For long argument, brittany uses

function
  loooooooooooooongarg1
  loooooooooooooongarg2

but I am pretty sure that I wouldn't want one-liner instances of function application like
foo = foldr a b to be split into multiple lines even if it is more consistent.

An example where imo the price of consistency would be too high is function application: For long argument, `brittany` uses ~~~~.hs function loooooooooooooongarg1 loooooooooooooongarg2 ~~~~ but I am pretty sure that I wouldn't want one-liner instances of function application like `foo = foldr a b` to be split into multiple lines even if it is more consistent.
Pitometsu commented 2017-09-20 21:09:19 +02:00 (Migrated from github.com)

Maybe it may be achieved by splitting all together in single one-liner, and than re-formatting.
So I try valid one-liner:

iiiiiiiiiiiiii :: Integer -> Integer; iiiiiiiiiiiiii = undefined; ffffffffffff :: Float -> Float -> Float; ffffffffffff = undefined

And got:

ERROR: brittany pretty printer returned syntactically invalid result.

UPD: just checked: stylish-haskell keep this snippet with no error, but hindent format it in nice way.

Maybe it may be achieved by splitting all together in single one-liner, and than re-formatting. So I try valid one-liner: ``` iiiiiiiiiiiiii :: Integer -> Integer; iiiiiiiiiiiiii = undefined; ffffffffffff :: Float -> Float -> Float; ffffffffffff = undefined ``` And got: ``` ERROR: brittany pretty printer returned syntactically invalid result. ``` **UPD:** just checked: `stylish-haskell` keep this snippet with no error, but `hindent` format it in nice way.
Pitometsu commented 2017-09-20 21:17:32 +02:00 (Migrated from github.com)

Yeah, you are right about function application.
What I want to achieve in general: process arbitrary formatted sources with brittany to get them in same style.

Yeah, you are right about function application. What I want to achieve in general: process arbitrary formatted sources with `brittany` to get them in same style.
lspitzner commented 2017-09-20 21:34:27 +02:00 (Migrated from github.com)

heh, yeah, you found a separate issue :p Feel free to report if it is a usecase you are really interested in.

I don't think that trick would work anyways. But it should be relatively easy to implement this without much trickery - conditionally remove some layouting alternatives (in certain instances, docAlt nodes already do that exact thing..)

Some other issues have higher priority, but after those I might find time to start implementing this.

What I want to achieve in general: process arbitrary formatted sources with brittany to get them in same style.

I get that, I just suspect you will have a hard time defining "same style" for all kinds of different input, and without things becoming ugly :-)

heh, yeah, you found a separate issue :p Feel free to report if it is a usecase you are really interested in. I don't think that trick would work anyways. But it should be relatively easy to implement this without much trickery - conditionally remove some layouting alternatives (in certain instances, `docAlt` nodes already do that exact thing..) Some other issues have higher priority, but after those I might find time to start implementing this. > What I want to achieve in general: process arbitrary formatted sources with brittany to get them in same style. I get that, I just suspect you will have a hard time defining "same style" for all kinds of different input, and without things becoming ugly :-)
Pitometsu commented 2017-09-20 21:55:13 +02:00 (Migrated from github.com)

Thank you for your work and this nice tool =)

Thank you for your work and this nice tool =)
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: hexagoxel/brittany#54
There is no content yet.