-
Notifications
You must be signed in to change notification settings - Fork 143
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
[style-guide] when expressions in match clauses #662
Comments
My personal preference is to always (even if it's only one) have |
I'm fairly inconsistent about this and jazz format a lot. A random selection of examples from dotnet/fsharp | ForEachThen (isFromSource, firstSourcePat, firstSource, JoinOrGroupJoinOrZipClause(nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), innerComp)
when
(let _firstSourceSimplePats, later1 =
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink
...) ->
Some ... and | ILMemberAccess.FamilyOrAssembly | ILMemberAccess.Assembly
when cenv.hasInternalsVisibleToAttrib -> true and | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _)
when firstTry = CompExprTranslationPass.Initial -> and | Expr.App (Expr.Link {contents = Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, [], _) }, _, [], args, m)
when localRep.IsValRepresentedAsMethod v && not (cenv.recUses.ContainsKey v) -> and match vspec.MemberInfo with
| None when
vspec.IsBaseVal ||
vspec.IsMemberThisVal && vspec.LogicalName = "__" -> false
| _ -> true As you can see, almost every imaginable style |
Perhaps
That would give: I'm fairly inconsistent about this and jazz format a lot. A random selection of examples from dotnet/fsharp | ForEachThen (isFromSource, firstSourcePat, firstSource, JoinOrGroupJoinOrZipClause(nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), innerComp)
when
(let _firstSourceSimplePats, later1 =
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink
...) ->
Some ... and | ILMemberAccess.FamilyOrAssembly | ILMemberAccess.Assembly
when cenv.hasInternalsVisibleToAttrib -> true and | OptionalSequential (JoinOrGroupJoinOrZipClause (_, _, _, _, _, mClause), _)
when firstTry = CompExprTranslationPass.Initial -> and | Expr.App (Expr.Link {contents = Expr.App (Expr.Val (ValDeref v, _, _), _, tyargs, [], _) }, _, [], args, m)
when localRep.IsValRepresentedAsMethod v && not (cenv.recUses.ContainsKey v) -> and match vspec.MemberInfo with
| None
when
vspec.IsBaseVal ||
vspec.IsMemberThisVal && vspec.LogicalName = "__" ->
false
| _ -> true I think the expression on the right of the |
That sounds reasonable to me. |
I'm not aware of any cases needing this. I checked this case where the expression after let f () =
match 1 with
| _
when
let x = 1
x > x -> 3
| _ -> 3 |
I raise you: let f () =
match 1 with
| _
when
match () with
| _ -> true ->
2
| _ -> 3 This could be an acceptable limitation, covered by the style guide. |
Yes, you're right, well-spotted :) |
Agreed this can be a known limitation |
I find it more clear when | ILMemberAccess.FamilyOrAssembly | ILMemberAccess.Assembly when
cenv.hasInternalsVisibleToAttrib -> true It also goes much more inline with other parts of the language where we place the keyword on the preceding line, like: while condition do
expression
if condition then
expression
match x with
| somePattern ->
expression and not like: while condition
do expression
someOtherOne
while condition
do
expression
if condition
then expression
match x with
| somePattern
-> expression It may be a problem when you want to place the right hand side expression on a new line, though, as it'll currently have the same indent as the match f a b c with
| someLongPattern, andAnotherOne when
let value = 1 + 2
someCondition ->
let a = someFunc someArg [] true
anotherFunc a 123 false If a style like this was automatically used by a formatter and by an IDE Enter typing assists, that could be a good option to consider. |
The reasoning to keep the match a with
| b when
c ->
d If |
For me the problem is that this leads to significant visual confusion between the expression on the right of the | ILMemberAccess.FamilyOrAssembly | ILMemberAccess.Assembly when
cenv.hasInternalsVisibleToAttrib ->
a>b compared to: | ILMemberAccess.FamilyOrAssembly | ILMemberAccess.Assembly
when cenv.hasInternalsVisibleToAttrib ->
a>b It only feels applicable if we decide we want small expressions on the right of the |
I would certainly vote for it! 🙂 |
I looked at this again and am still inclined to follow the rules here: #662 (comment) There are real readability issues with the I'll leave this open to discuss further however as both @nojaf and @auduchinok have said "put the when at the end" :) |
"when" at the start does also make sense to me. |
In the cases provided earlier in the thread, I believe that I mentally bucket I think about how in some other languages, they can omit keywords like |
Hello,
The current style guide does not give any guidance on where to put the
when
expression in match clauses.Some examples:
In small expressions, it makes sense to put the
when expr
after the pattern.There is a bit of a problem when the
when expr
is getting large or contains multiple lines.Some samples
My personal view on this is if you have a multiline
when
expression, you should probably refactor it to a partial active pattern and encapsulate your logic there.Regardless, what advice should be given when this problem arises?
I'm interested in the position of the
when
keyword, newlines and/or indentations of the multiline expression and the position of the->
arrow.Thoughts @dsyme and community?
The text was updated successfully, but these errors were encountered: