Skip to content

[Poll] Consider changing the default of fsharp_multiline_bracket_style #3200

Description

@nojaf

Hello everyone,

I recently had a conversation about how Fantomas formats records by default (fsharp_multiline_bracket_style = cramped).

There’s a configuration setting for this: fsharp_multiline_bracket_style.

The benefit of the cramped style is that it’s compact and may feel familiar to developers coming from OCaml or Haskell.

let myRecord =
    { Level = 1
      Progress = "foo"
      Bar = "bar"
      Street = "Bakerstreet"
      Number = 42 }

type Range =
    { From: float
      To: float
      FileName: string }

let a =
    [| (1, 2, 3)
       (4, 5, 6)
       (7, 8, 9)
       (10, 11, 12)
       (13, 14, 15)
       (16, 17, 18)
       (19, 20, 21) |]

The main drawback of this style is that it’s harder to manipulate record fields during copy/paste operations.
Indentation can also feel slightly off:

// indent_size = 4
let myRecord =
// Start of { at 4 spaces
    { Level = 1
// Start of record field at 6 spaces
      Progress = "foo"

This breaks what I call the “indentation flow.”
This topic deserves its own discussion, but it’s not the main focus here.

The other available styles (aligned and stroustrup) do not have this issue:

// aligned
let myRecord =
    {
        Level = 1
        Progress = "foo"
        Bar = "bar"
        Street = "Bakerstreet"
        Number = 42
    }

type Range =
    {
        From: float
        To: float
        FileName: string
    }

let a =
    [|
        (1, 2, 3)
        (4, 5, 6)
        (7, 8, 9)
        (10, 11, 12)
        (13, 14, 15)
        (16, 17, 18)
        (19, 20, 21)
    |]

// stroustrup
let myRecord = {
    Level = 1
    Progress = "foo"
    Bar = "bar"
    Street = "Bakerstreet"
    Number = 42
}

type Range = {
    From: float
    To: float
    FileName: string
}

let a = [|
    (1, 2, 3)
    (4, 5, 6)
    (7, 8, 9)
    (10, 11, 12)
    (13, 14, 15)
    (16, 17, 18)
    (19, 20, 21)
|]

These styles make it easier to add or remove record fields, and indentation stays consistent with multiples of the indent_size.

The F# style guide mentions all three of these styles.

So, the key question is:

Should we reconsider the default style?

We (the Fantomas core team) would like to get a sense of how the community feels about this.
We are not promising any changes, but if there is strong community consensus in favour of something else, we will consider it seriously.

This has been the default for many years, so we will not make any changes lightly.

That said, we’d love to hear your preference.
Please react to the first message in this issue with:

  • 👀 if you prefer to keep the current default (cramped)
  • 🎉 if you’d prefer aligned
  • 🚀 if you’d prefer stroustrup

We’ll only count reactions to the first post in this issue.
Reactions or opinions elsewhere will not be included.

//cc @dawedawe @josh-degraw

Activity

  1. changed the title [-][Poll] Consider changing the default of[/-] [+][Poll] Consider changing the default of fsharp_multiline_bracket_style[/+] on Nov 8, 2025
  2. charlesroddie commented on Nov 8, 2025

    @charlesroddie

    Cramped has inconsistent indentation, sometimes 4, 3, or 2 spaces, so should be binned.

  3. richardcox13 commented on Nov 8, 2025

    @richardcox13

    As a proponent of the One True Brace Style in C family languages I would prefer the Stroustrup option.
    It offers the same vertical space saving as compact vs. aligned, while avoiding the odd indentation.

  4. WillEhrendreich commented on Nov 9, 2025

    @WillEhrendreich

    I find stroustrop the nicest to work with.

    Switching the order of things is great with every line then, it doesn't matter which comes first or last, I can swap lines without doing extra work to move the bracket.

    It's also has the best trade off for indent vs number of lines I think.

  5. pkese commented on Nov 9, 2025

    @pkese

    In F# you can also add methods to a record type,
    which is also not standardized.

    I'm writing it as:

    type Range = {
        From: float
        To: float
        FileName: string
    } with
        member this.FromToString() =
            $"{this.From}-{this.To}"
  6. ursenzler commented on Nov 10, 2025

    @ursenzler
    Contributor

    I'm team "aligned" because I like the symmetry that helps my eyes parse code faster - even if the code is one line longer per record.
    As long as there is a setting for the style, I'm totally okay with a different default style.

  7. ShalokShalom commented on Nov 10, 2025

    @ShalokShalom
    Contributor

    I decided to choose stroupstrup, since it is the closest to the indendation based style that we are used from FSharp otherwise.

    Its also the easiest to read, I think.

  8. auduchinok commented on Nov 10, 2025

    @auduchinok
    Contributor

    Just to add a bit from the tooling and language design perspective. F# is indentation sensitive, and there are many cases where allowing something to be less indented makes it less suitable for the editor tooling. In the last couple of years we've significantly improved quality of the parser recovery during typing and many of these improvements assume that inner parts of expressions/statements are always more indented.

    Stroustrup looks great and has many advantages, but out of these three styles it works the worst with the F# parser, because it was invented with a different language family in mind.

  9. overtongeist commented on Nov 11, 2025

    @overtongeist

    From the current vote count (24-aligned, 84-stroustrup, 10-keepCurrentDefault) seems clear to me that the default should change. However, I'd argue that @auduchinok's input here is important, so maybe stroustrup should not be the default to switch to? (I'm biased, I'm team-aligned)

  10. nojaf commented on Nov 11, 2025

    @nojaf
    ContributorAuthor

    From the current vote count

    We need more input before deciding. So far the votes suggest a different option is preferred as the default, but that is relative: Fantomas averages about 500 downloads per day according to the NuGet stats. The NuGet numbers don't show the full picture of all users. It's hard to reach everyone, which is why we want to hear enough voices before making a decision.

  11. Martin521 commented on Nov 11, 2025

    @Martin521
    Contributor

    Just to add a bit from the tooling and language design perspective. F# is indentation sensitive, and there are many cases where allowing something to be less indented makes it less suitable for the editor tooling. In the last couple of years we've significantly improved quality of the parser recovery during typing and many of these improvements assume that inner parts of expressions/statements are always more indented.

    Stroustrup looks great and has many advantages, but out of these three styles it works the worst with the F# parser, because it was invented with a different language family in mind.

    The parser has to support all three options anyway. This is just about the Fantomas default.

  12. nojaf commented on Nov 11, 2025

    @nojaf
    ContributorAuthor

    The parser has to support all three options anyway. This is just about the Fantomas default.

    "Has to" is a bit of an assumption. The parser mostly supports three styles until it doesn't. You can probably write some extreme Stroustrup-style code that will hit parser limitations.

    Overall, and I don't mean to be negative, F# wasn't designed with a formatter in mind. The parser accepts certain constructs, but code styling was never part of its original design, so these behaviors are more accidental.

    Eugene's remark is valuable input. If we make Stroustrup the default, I expect more issues from people exploring uncharted territory where parser limitations may come into play.

  13. Martin521 commented on Nov 11, 2025

    @Martin521
    Contributor

    "Has to" is a bit of an assumption. The parser mostly supports three styles until it doesn't.

    As far as I know, Stroustrup style has been valid F# since the "lightweight syntax" was introduced and was always part of the spec (§15.1.4). I have a hard time imagining the parser will stop to support it.

  14. 13 remaining items

  15. drk-mtr commented on Nov 15, 2025

    @drk-mtr

    I like stroustrup best aesthetically, voted aligned as it feels like the safest default for the reasons already mentioned. Not in to cramped.

  16. auduchinok commented on Nov 19, 2025

    @auduchinok
    Contributor

    @auduchinok, does Stroustrup have negative effects compared to aligned on the dev experience inside the IDE?

    Yes, exactly like the cases above where the parsing breaks, and I suspect there may be more. Almost all IDE features rely on reasonably good parsing.

  17. cr3wdayt5p commented on Nov 21, 2025

    @cr3wdayt5p

    We (the Fantomas core team) would like to get a sense of how the community feels about this.

    We need more input before deciding. So far the votes suggest a different option is preferred as the default, but that is relative: Fantomas averages about 500 downloads per day according to the NuGet stats. The NuGet numbers don't show the full picture of all users. It's hard to reach everyone, which is why we want to hear enough voices before making a decision.

    @nojaf How much does the language-adoption perspective play into this decision?

    The result of this poll may represent how the existing F# community feels about the indentation style.

    But since it is just the default value you are considering changing, would the not-yet-F# developers not be a better target for the poll? At least seen from the language-adoption perspective.

    I.e. ask 200 random TypeScript developers what style they would find the easiest to transition into.

    My guess would be stroustrup :)

    If changing the default value to stroustrup could remove even a tiny bump on the F# adoption path, then I think that argument alone is enough reason to do it.

    Some consistency enthusiasts may still switch to aligned, and newcomers from OCaml/Haskell may choose cramped for the familiarity.

  18. recumbent commented on Nov 22, 2025

    @recumbent

    I love how we've adopted a measure introduced solely to save space in a printed book - where extra space == additional cost - as the ideal standard 😢 Its not like we print listings to fix errors/debug/review any more either (I have two copies of the book and have scribbled on a lot of printed listings)

    Whitespace is more or less free - having matching pairs of things aligned is helpful to the bits of the brain that do pattern matching. 🦕👈me

  19. lenscas commented on Nov 22, 2025

    @lenscas

    Its not like we print listings to fix errors/debug/review any more either (I have two copies of the book and have scribbled on a lot of printed listings

    Speak for yourself, I hook up all my applications up to whatever printer is available on the network to automatically print out the error, stack trace and if possible relevant code. I make the compiler print out errors like this as well.

    This way, everything is nicely documented for future reference.

  20. nojaf commented on Nov 23, 2025

    @nojaf
    ContributorAuthor

    But since it is just the default value you are considering changing, would the not-yet-F# developers not be a better target for the poll? At least seen from the language-adoption perspective.

    Language adoption is not something we consider here. I personally don't see that spike anymore.

    Yes, a TS developer might be more familiar with Stroustrup, while a Haskell developer would give a different answer. I don't put much stock in the "other language or formatter does X or Y" trope. You can always pick an example that fits your narrative.

  21. drk-mtr commented on Nov 23, 2025

    @drk-mtr

    Indeed. A counter argument is that as soon as a Typescript developer finds a case where they have to move away from stroustrup because it doesn't work for their case, that is friction.

  22. cr3wdayt5p commented on Nov 23, 2025

    @cr3wdayt5p

    Language adoption is not something we consider here.

    That is fair (although I am not sure I agree). Maybe it should have been more explicit in the poll description? The "how the community feels about this" is a bit broad :)

    Indeed. A counter argument is that as soon as a Typescript developer finds a case where they have to move away from stroustrup because it doesn't work for their case, that is friction.

    From my experience with using stroustrup in a large-ish repo (now ~280k lines) there have never been a reason to move away from stroustrup. Although at very rare occasions I have experienced something similar to the let timeline = [ ... ] issue mentioned above. But that has never been enough of a reason to switch to aligned.




    [...] if there is strong community consensus in favour of something else, we will consider it seriously.

    With the current poll status of 186 (47+139) for "something else" and only 15 for "keep current" I would say there is strong community consensus for "something else" with 92.5% of the votes (186/201).

    I voted for stroustrup due to the aesthetics and familiarity / language-adoption reasons (also why we use it). But with the potential minor issues with stroustrup highlighted in this thread I am not sure it is the best default for the F# language.

    I think aligned might be a slightly better default. It is very consistent and has none of the technical or UX issues. Its only downsides is the (subjectively) slightly less appealing aesthetics and the fact that it is 1 line longer than stroustrup.

    I tested the "1 line longer" aspect on our codebase of ~280k lines of stroustrup formatted code. With aligned the codebase grows to ~290k lines, i.e. ~4 % more lines. That is number is naturally very repo-specific. But it appears to not be that bad in practices.

    Main point: The non-clear preference between stroustrup and aligned should not be a blocker. I would argue that all these votes should be counted as "something else" votes foremost, and only secondarily as votes for either stroustrup or aligned.


    I will continue to use stroustrup for the reasons listed above but I would still be very happy if the default was changed to aligned. That would also result in new greenfield code from AI agents being nicely formatted by default without an .editorconfig file – a simple "use fantomas" instruction would be enough. If language-adoption was a main concern I would however still lean towards stroustrup as the new default.

  23. nojaf commented on Dec 15, 2025

    @nojaf
    ContributorAuthor

    Hello all,

    Thank you everyone for participating in this conversation and for voting.

    Based on the votes, cramped is the least preferred style, so it is sensible to change the default.

    Although stroustrup appears to be the most popular, we prefer to be cautious and proceed with aligned instead. The F# parser has some corner cases when parsing stroustrup, which can lead to parsing errors.

    If the parser improves sufficiently over time, we can reconsider stroustrup as the default.

    A first alpha release with the changed default is available at:

    https://github.com/fsprojects/fantomas/releases/tag/v8.0.0-alpha-002

  24. nojaf commented on Feb 19, 2026

    @nojaf
    ContributorAuthor

    Hi all, I'm considering releasing v8 as stable.

    The only significant changes would be FCS update and the change of default for fsharp_multiline_bracket_style.

    I haven't heard any feedback, so I assume all is well. If not, speak now or never.

  25. github-actions commented on Apr 20, 2026

    @github-actions
    Contributor

    🤖 This is an automated response from Repo Assist.

    Thanks for running this community poll! Here's a snapshot of the current results from the first post's reactions:

    Style Votes Share
    🚀 Stroustrup 157 70 %
    🎉 Aligned 51 23 %
    👀 Cramped (current default) 16 7 %

    Total reactions: 224 — a strong community signal that Stroustrup is the preferred default.

    A few things worth considering if maintainers decide to change the default:

    1. Migration impact: changing the default will alter the on-disk output for any codebase that doesn't explicitly set fsharp_multiline_bracket_style in .editorconfig. This is a formatting-only change (no compile errors), but it will produce noisy diffs in codebases that rely on the implicit default.

    2. Transition path: a good practice would be to document the migration clearly in the release notes — e.g. "if you want to keep the old default, add fsharp_multiline_bracket_style = cramped to your .editorconfig."

    3. Timing: since 8.0.0 is already an alpha with several breaking changes, this could be a good release to bundle this default change in, so users only go through one major migration.

    The community preference is clear. The decision is, of course, yours — just flagging that the data makes a compelling case.

    Generated by 🌈 Repo Assist, see workflow run. Learn more.

    Generated by 🌈 Repo Assist, see workflow run. Learn more.

    To install this agentic workflow, run

    gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions