fslang-design icon indicating copy to clipboard operation
fslang-design copied to clipboard

[style-guide] Multiline application in patterns

Open nojaf opened this issue 3 years ago • 2 comments

Hello,

What should the guidance be for multiline (function?) applications in patterns? Example:

match myString with
| Regex @"^(\w+) can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.$" [ name; speed; flyTime; restTime ] ->
    ()

Imagine this pattern doesn't respect the max_line_length, how should it be formatted multiline?

This

match myString with
| Regex 
    @"^(\w+) can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.$" 
    [ name; speed; flyTime; restTime ] ->
    ()

comes to mind.

Related, patterns do seem to have some funky offset rules from time to time. The same example wrapped in a record:

match myString with
| { X = Regex 
            @"^(\w+) can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.$" 
            [ name
              speed
              flyTime
              restTime ] } ->
    ()

Notice that:

match myString with
| { X = 
        Regex 
            @"^(\w+) can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.$" 
            [ name
              speed
              flyTime
              restTime ] } ->
    ()

is invalid F# code. (online tool)

Another interesting case is:

match myString with
| X(
    Regex 
        @"^(\w+) can fly (\d+) km/s for (\d+) seconds, but then must rest for (\d+) seconds\.$" 
        [ name
          speed
          flyTime
          restTime ] 
  ) ->
    ()

This is valid code, thought the closing ) needs to be aligned with the X column.

@dsyme any thoughts on this?

nojaf avatar Nov 03 '22 08:11 nojaf

Glad you brought this up, though function application in patterns, where there's more than one argument, is pretty rare. More often this is coded to accept a tuple. But that's besides the point you're trying to make.

Isn't your first example invalid code? You have this in the list code: [ name speed flyTime restTime ], but in the follow-up, you have the equivalent of [ name; speed; flyTime; restTime ]. Which really are two different things.

Those offset rules are a bit worrying though.

TBH: my vote would probably be for leaving it on one line. That's probably gonna be controversial (isn't everything related to formatting?).

But then again, that pairs pretty badly with a multiline list, seq or array construction.

Hmm, I recant that idea. To be in line with the other function application rules, aligning them like your first example appears most sensible, tbh. But any which way I look at it, it's hard to think of any formatting that would improve the readability of such code...

abelbraaksma avatar Nov 03 '22 16:11 abelbraaksma

I would say we should split like in the first example.

Related, patterns do seem to have some funky offset rules from time to time.

This seems like a bug and I can see it makes the splitting hard to implement.

dsyme avatar Dec 07 '22 17:12 dsyme