-
-
Notifications
You must be signed in to change notification settings - Fork 194
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
Confusing symmetry between infix operators #988
Comments
Why? Because compilation breaks? I think you can workaround this by increasing MaxInfixOperatorExpression |
Sorry the short description. Compilation is fine, but I find path.Length
>= currentIncludePath.Length
+ 1 to be very confusing to read. There shouldn't be visual symmetry between ```f#
path.Length
>= currentIncludePath.Length
+ 1 Ideally By the way, I misread the intentation here:
I think the indentation here makes sense. Sorry about the issue title, by the way 😅 |
Hey @cmeeren So
This is a bit point of view I'm afraid. From a logic perspective, I'd yes agreed. However, Fantomas has no idea what operators like There a few exceptions to this: newLineInfixOps and noBreakInfixOps . We could add Not sure what other options we have here. |
(Emphasis mine) So it's not just a matter of taste, it's more an implementation challenge? I'll think about this and get back to you. |
Indeed, Fantomas has no idea what your code does and if it even makes sense. |
I think this may be solved by Fantomas knowing about operator precedence. Quasi algorithm:
Do this recursively, of course. |
So if we have
a + b
* c Like that? |
If
EDIT: which is actually what @cmeeren was proposing as algorithm in his last comment |
@knocte yes indeed, my bad, thanks for the correction. |
If not, perhaps the order of operators could be hardcoded for now. |
Hey, I'm trying to give this issue a shot by having a better way of splitting the infix operators. type Associativity =
| Right
| Left
| NonAssociative
type InfixOperatorMeta =
{ Priority: int
Associativity: Associativity
PreferOnNewline: bool }
// Not sure if a fixed map is workable
// https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/#operator-precedence
let operatorMeta =
[ "+", { Priority = 1; Associativity = Left; PreferOnNewline = false }
"-", { Priority = 1; Associativity = Left; PreferOnNewline = false }
"*", { Priority = 2; Associativity = Left; PreferOnNewline = false }
"|>", { Priority = 3; Associativity = Left; PreferOnNewline = false }
"=", { Priority = 3; Associativity = Left; PreferOnNewline = false }
"&&", { Priority = 4; Associativity = Left; PreferOnNewline = false } ]
|> Map.ofList And then in the CodePrinter you try and split on the lowest priority. [<Test>]
let ``simple math`` () =
formatSourceString false """let myValue = a + b * c
""" { config with MaxInfixOperatorExpression = 5 }
|> prepend newline
|> should equal """
let myValue =
a +
b * c
"""
[<Test>]
let ``simple math in one line`` () =
formatSourceString false """let myValue = a + b * c
""" { config with MaxInfixOperatorExpression = 50 }
|> prepend newline
|> should equal """
let myValue = a + b * c
"""
[<Test>]
let ``simple math reversed`` () =
formatSourceString false """let myValue = a * b + c
""" { config with MaxInfixOperatorExpression = 5 }
|> prepend newline
|> should equal """
let myValue =
a * b
+ c
"""
[<Test>]
let ``multiple sum operators`` () =
formatSourceString false """let myValue = a + b * c + d
""" { config with MaxInfixOperatorExpression = 5 }
|> prepend newline
|> should equal """
let myValue =
a +
b * c +
d
""" Now the first thing I'm struggling with it deciding when an operator should be added before or after the expression. let x =
a * b +
c same problem for always at the front let x =
a
+ b * c I'm open for suggestions on this. |
IMHO code is easier to read if the operators are at the front. But in any case, if you treat all operators the same (not just arithmetic operators), you kinda have to, because no-one wants: let exec f x =
x |>
f The only sensible option here is: let exec f x =
x
|> f
I don't see any problem with this. Of course, it's a bit artificial since the line is so short, but given |
IMO
and
|
I then suggest that it be made configurable whether to break with operators at the end or at the front. |
FWIW, the reason I find front operators more readable is a combination of 1) operators we break at are more "important" for readability given their associativity in the hierarchy, and 2) placing them at the front makes them easier to see since a) they are all aligned, and b) you don't have to hunt for them far to the right if you have long lines. |
No, just no 🙃. Sorry, this is really unmaintainable to have a setting for each operator. Especially when users can have custom operators. Maybe Fantomas can store an opinioned preferred location for some operators and have a default at the front. But then again, I agreed with @cmeeren his last remarks. |
I meant one setting for all operators. Completely agree that one setting per operator is nuts. 😛
👍 |
Thanks! I'll let you know. |
Issue created from fantomas-online
Code
Result
Problem description
The following:
Should be on one line:
Also, this is weirdly formatted (line break and indentation):
Extra information
Options
Fantomas Master at 07/20/2020 08:56:02 - d42a156
IndentSize
4
MaxLineLength
120
SemicolonAtEndOfLine
false
SpaceBeforeParameter
true
SpaceBeforeLowercaseInvocation
true
SpaceBeforeUppercaseInvocation
false
SpaceBeforeClassConstructor
false
SpaceBeforeMember
false
SpaceBeforeColon
false
SpaceAfterComma
true
SpaceBeforeSemicolon
false
SpaceAfterSemicolon
true
IndentOnTryWith
false
SpaceAroundDelimiter
true
MaxIfThenElseShortWidth
40
MaxInfixOperatorExpression
50
MaxRecordWidth
40
MaxArrayOrListWidth
40
MaxValueBindingWidth
40
MaxFunctionBindingWidth
40
MultilineBlockBracketsOnSameColumn
false
NewlineBetweenTypeDefinitionAndMembers
false
KeepIfThenInSameLine
false
MaxElmishWidth
40
SingleArgumentWebMode
false
AlignFunctionSignatureToIndentation
false
AlternativeLongMemberDefinitions
false
StrictMode
false
The text was updated successfully, but these errors were encountered: