-
Notifications
You must be signed in to change notification settings - Fork 21
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
Warn when undentation of operators causes ambiguity when following a match or if-else block #806
Comments
To quote @dsyme from this above referenced thread of 2016, a bug report by @smoothdeveloper (thanks for pointing it out to me):
To answer that last line, I think we can do one of two things:
Not sure whether either of above options is easy or hard to detect in practice and whether corner cases exist that are not covered by such a simple rule. (side note, @cartermp, I don't know how relevant these labels are, but I don't think my suggestion has to do with either type-checking or inference. I'm not trying to suggest a change in either. If anything, it is probably syntax related, or improving user experience, or the F# tokenizer/parser) |
These undentations are bad in general surely. That's what the ambiguities show. Rather than warning only when bad undentations cause ambiguities, we should warn whenever they are made. That would be a lot clearer to users and also simpler for the compiler. I.e. in
This code is currently explicitly allowed in the F# language spec: let x =
expr
+ expr
let x =
expr
|> f expr I don't see why though. Is this considered good style? The behaviour in this thread seems to refute this. |
@charlesroddie I don't think anybody considers it good style. At best it's mentioned in some text books. But in practice, I see everyone align on the start of the operator. The only exceptions to the rule are, however, any form of parens, brackets, curlies. Here, the first item starting with an opening paren, bracket or curly, is undented one character, so that the actual code inside the brackets aligns. Most bracket constructs use one character, but there's also |
Shouldn't the scope of this issue be undentation of operators, since bracket undentation doesn't give the ambiguities mentioned? |
Thanks for approving this, @dsyme. I'll see if I can create an RFC. |
Would the suggested Warning show here too? |
@goswinr, yes, this suggestion was meant specifically for such cases, see my description in the original issue, as that describes your SO question exactly. |
I really hope this gets into the language! It has bitten me more than once. Especially when I write a quick script for some side effects logic here or there. (Incomplete IF expressions that return UNIT, like in my SO question) It’s hard to debug. And I couldn’t even plausibly explain the reason why its like that to an F# beginner. Someone on SO even answered its a bug and i should raise an issue. He later deleted that answer. |
Warn for undentation ambiguities caused by operators
Note: this is undentation, or indentation-relaxation, not indentation.
I propose we raise a warning when undentation relaxation for operators will lead to ambiguities. This warning can be raised when the parser detects that after undenting an operator for the width of the operator, would make it belong to the previous block instead of the last statement. The warning could be:
Rationale
The issue discussed here is notoriously hard to spot in a code base. I've been bitten by it numerous times over the cause of many years F# programming, and I am presently unsure whether my code silently has bugs caused by the indentation-relaxation rules for operators.
It is well established that F# is a whitespace-sensitive language, where generally related statements must start at the same indentation level.
For operators, there's an exception, where the parser will allow the operator to be undented until the rh-side of the operator is at the same line as the previous line. When the operator changes type, this is not a problem and wrongful use will lead to errors:
In the examples above, it is clear, because the type inference will raise an exception (though the exception by itself will be hard to understand as it will be about the type, not the undentation error).
If we change this a little and create an operator for logging, it becomes must harder to detect:
The problem is most apparent with operators that don't change type, because otherwise the chance of detection is much larger as it will likely raise a compile-time error.
The existing way of approaching this problem in F# is: to live with it and spot such errors visually (and as multiple reports have shown, this can be rather hard, even for seasoned developers).
Pros and Cons
The advantages are:
Extra information
Estimated cost (XS, S, M, L, XL, XXL): XS (I really hope that's true)
Related suggestions:
|>
operator inmatch
block: https://stackoverflow.com/questions/45272356/which-match-with-indentation-rule-is-at-play-hereAffidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
If this is going to be accepted and someone can point me to the location where the indentation-relaxation of operators takes place, I'll gladly take a look to see if I can have that code raise a warning for ambiguous scenarios.
The text was updated successfully, but these errors were encountered: