anoma / juvix

A language for intent-centric and declarative decentralised applications
https://docs.juvix.org
GNU General Public License v3.0
449 stars 54 forks source link

Make `juvix format` line width 100 with ribbon width 100 #2883

Closed paulcadman closed 2 months ago

paulcadman commented 2 months ago

This PR increases the ribbon width of juvix format from 60 to 100 characters.

Reasons for the compromise to a fixed 100 chars ribbon width:

Definition of ribbon width from the docs

The page has a certain maximum width, which the layouter tries to not exceed, by inserting line breaks where possible. The functions given in this module make it fairly straightforward to specify where, and under what circumstances, such a line break may be inserted by the layouter, for example via the sep function.

There is also the concept of ribbon width. The ribbon is the part of a line that is printed, i.e. the line length without the leading indentation. The layouters take a ribbon fraction argument, which specifies how much of a line should be filled before trying to break it up. A ribbon width of 0.5 in a document of width 80 will result in the layouter to try to not exceed 0.5*80 = 40 (ignoring current indentation depth).

Examples from anoma-app-patterns:/Token/Transaction.juvix. NB: The file in the repo is unformatted so will not match the layout in the left column below.

Current (line width 150, ribbon width 60) This PR (line width 100, ribbon width 100)
Screenshot 2024-07-10 at 12 22 46 Screenshot 2024-07-10 at 14 41 33
Screenshot 2024-07-10 at 12 23 10 Screenshot 2024-07-10 at 14 42 01
Screenshot 2024-07-10 at 12 23 21 Screenshot 2024-07-10 at 14 42 14
Screenshot 2024-07-10 at 12 23 34 Screenshot 2024-07-10 at 14 42 29
Screenshot 2024-07-10 at 12 23 50 Screenshot 2024-07-10 at 14 42 40
Screenshot 2024-07-10 at 12 24 13 Screenshot 2024-07-10 at 14 42 57
heueristik commented 2 months ago

Setting the ribbon width to 100 is too large because it's common for text editors to have buffer width around 80 characters.

Two questions: Which editors wouldn't be able to display code with >80 chars properly? Will this encourage people to write very short, non-descriptive variable names in production code? This could lead to more errors.

lukaszcz commented 2 months ago

Two questions: Which editors wouldn't be able to display code with 80 chars properly?

VSCode with two panes on my 24 inch screen with a 14pt font and 1920x1080 resolution. Then one pane displays 80-something characters.

Will this encourage people to write very short, non-descriptive variable names in production code? This could lead to more errors.

I don't think so. It's not Java. The rest of the language is quite succinct, so there's space for variable names. Plus, you put newlines a lot more, with every case etc. 80 is not such a small number.

We're basically using around 80 characters per line in our Haskell code. I definitely don't write much longer lines. It works well.

heueristik commented 2 months ago

Maxim: "juvix format's style is no one's favourite, yet juvix format is everyone's favourite" (thanks go fmt)

It is also worth noting that go fmt has no line length limit:

Go has no line length limit. Don’t worry about overflowing a punched card. If a line feels too long, wrap it and indent with an extra tab.

https://go.dev/doc/effective_go#formatting

lukaszcz commented 2 months ago

Maxim: "juvix format's style is no one's favourite, yet juvix format is everyone's favourite" (thanks go fmt)

It is also worth noting that go fmt has no line length limit:

Go has no line length limit. Don’t worry about overflowing a punched card. If a line feels too long, wrap it and indent with an extra tab.

https://go.dev/doc/effective_go#formatting

There’s a point here. I think ormolu doesn’t break the lines by itself either, only in situations when e.g. there is already one newline after a case. The question is how uniform we want to be.

Though “wrap it and indent with an extra tab” doesn’t work too well with complex code structure - quickly becomes unreadable when there are many such lines.

lukaszcz commented 2 months ago

I'd say not enforcing a line length limit is less strict than having an option to enforce different line length limits. It allows people to choose the line length arbitrarily and differently within even a single project.

lukaszcz commented 2 months ago

For me personally, ribbon width of 100 chars would still be palatable, but with anything longer than this used consistently I'd need to give up on two panes side by side.

paulcadman commented 2 months ago

I'd say not enforcing a line length limit is less strict than having an option to enforce different line length limits. It allows people to choose the line length arbitrarily and differently within even a single project.

I think we can agree on this. Q: can we implement this using prettyprinter, if so what's the effort required? Perhaps @janmasrovira knows?

paulcadman commented 2 months ago

For me personally, ribbon width of 100 chars would still be palatable, but with anything longer than this used consistently I'd need to give up on two panes side by side.

Thanks - I'll update this PR to line width 100 and ribbon width 100 (i.e 100 1.0).

paulcadman commented 2 months ago

Maxim: "juvix format's style is no one's favourite, yet juvix format is everyone's favourite" (thanks go fmt)

It is also worth noting that go fmt has no line length limit:

Go has no line length limit. Don’t worry about overflowing a punched card. If a line feels too long, wrap it and indent with an extra tab.

https://go.dev/doc/effective_go#formatting

For clarity I didn't make this comment to endorse all of gofmts design choices, just the maxim.

lukaszcz commented 2 months ago

For me personally, ribbon width of 100 chars would still be palatable, but with anything longer than this used consistently I'd need to give up on two panes side by side.

Thanks - I'll update this PR to line width 100 and ribbon width 100 (i.e 100 1.0).

Palatable, but a bit inconvenient. I won't protest against ribbon width 100, but would prefer something a bit smaller.

janmasrovira commented 2 months ago

I'm fine with either choice. Let's try it for a while, if we feel like it can be improved, we can always change it.

I'd like to add that we don't respect the user newlines by design. The goal of our formatter is indeed to make code look readable, but also (and not less important) to remove as much formatting responsability from the user as possible.

paulcadman commented 2 months ago

I now realize that some changes are needed in the Format.juvix test. Some lines were written with the intention to force the formatter to introduce a newline.

Thanks - I'll fix these now