Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatting conventions for anonymous records (expressions and types) not explicitly given #8

Open
Fizzixnerd opened this issue Sep 26, 2020 · 4 comments

Comments

@Fizzixnerd
Copy link

The formatting conventions for records do not mention anonymous records. Personally I would assume the rules are the same for expressions as for records, but the case of types is left (I believe) ambiguous currently.

Consider the following use of anonymous records as types:

type A =
    {|
        x: int
        y: AReallyLongTypeThatIsMuchLongerThan40Characters
    |}

let f (x: {|
              x: int
              y: AReallyLongTypeThatIsMuchLongerThan40Characters
          |}) =
    x

The case of A is rather straight-forward (leaving aside the code smell of giving an anonymous record a type alias) and follows the rules for normal records in the type position. The case for f is a little more ambiguous and I believe requires clarification. See also this fantomas issue.

@Smaug123
Copy link
Contributor

Case A is indeed straightforward and is as you write (except that GR puts a space before the colon: x : int).

Case B is thoroughly odd, and I'm inclined to say "do whatever, it won't come up at GR". However, for the sake of completeness, I'd probably format it as follows:

let f
    (x :
        {|
            x : int
            y : AReallyLongTypeThatIsMuchLongerThan40Characters
        |}
    )
    =
    x

although I am torn between that and:

let f
    (
        x :
            {|
                x : int
                y : AReallyLongTypeThatIsMuchLongerThan40Characters
            |}
    )
    =
    x

Both options seem terrible.

@nojaf
Copy link
Contributor

nojaf commented Sep 28, 2020

Another example:

let internal sepSemi (ctx: Context) =
    let { Config = { SpaceBeforeSemicolon = before
                     SpaceAfterSemicolon = after } } =
        ctx

What would you make of this @Smaug123? Likely to occur at GR?

@Smaug123
Copy link
Contributor

I'd say that's quite unlikely - we'd more explicitly let before = ctx.Config.SpaceBeforeSemicolon and so on, I imagine. But I'd format it as follows, if this handwritten code is valid F#:

let internal sepSemi (ctx : Context) =
    let
        {
            Config =
                {
                    SpaceBeforeSemicolon = before
                    SpaceAfterSemicolon = after
                }
        }
        = ctx

I'd probably go to almost any lengths to avoid doing this, though.

We do have examples like:

let foo
    {
        Bar = bar
        Baz = baz
    }
    =
    bar

(if that compiles), although I suspect I wrote most of them personally; I wouldn't object too much to the following style:

let foo
    ({
        Config =
            {
                SpaceBeforeSemicolon = before
                SpaceAfterSemicolon = after
            }
    } as ctx)
    =
    bar

@Smaug123
Copy link
Contributor

Basically I think there's no way to satisfy me that any possible options here are aesthetically pleasing, so I don't much mind what we do with them - I would resist allowing any examples through code review anyway :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants