Proposal: Single-line if statements #1785
Replies: 51 comments
-
|
Beta Was this translation helpful? Give feedback.
-
Allowing a superfluous |
Beta Was this translation helpful? Give feedback.
-
This is unlikely to ever gain acceptance, but if you like the idea, have a look at the Boo language, where option C is supported and considered idiomatic. 😄 |
Beta Was this translation helpful? Give feedback.
-
@HaloFour I see that you like to bring this up on various proposals, but there's a huge difference that you repeatedly miss.
The goal of this proposal (and others like it) is to find a way to write the code in a single line that is legal, succinct, readable, and not ambiguous (and thus not discouraged). This follows the same line of thought that brought about expression-bodied members. And yes, it has been brought up multiple times, because multiple people would like to find a solution. This issue would encompass #1493, #724. #453 and #325 change the syntax a bit, but are after the same goal. |
Beta Was this translation helpful? Give feedback.
-
if |
Beta Was this translation helpful? Give feedback.
-
@jnm2 The problem with #1210 and #1567 is that they are trying to apply a construct that works well for single- line, single-block statements and try to apply them to multi-block cases, which hasn't worked out great. This proposal avoids that. #1540 wanted expression-bodied members to accept statement-bodied members, which I reject in option A. |
Beta Was this translation helpful? Give feedback.
-
There's nothing ambiguous about I don't like the idea of inventing new syntax just to workaround overzealous code style requirements. When those same enterprises then forbid this syntax on the same grounds are you going to suggest another syntax to avoid those requirements? |
Beta Was this translation helpful? Give feedback.
-
@masonwheeler No need to be facetious. Obviously, I'm here because I like C#. I'm not going to change languages over any single feature! That said, this construct is also fully supported by Perl and Ruby, so there are at least three languages that already support this. |
Beta Was this translation helpful? Give feedback.
-
// 1.
if (arg == null) => throw new ArgumentNullException(nameof(arg)); Why not just do: if (arg == null) { throw new ArgumentNullException(nameof(arg)); } It's only one character longer... |
Beta Was this translation helpful? Give feedback.
-
Your proposal does not enable something that was previously impossible, make easy something that was previously hard, increase readability, or increase productivity. That's a no for me. |
Beta Was this translation helpful? Give feedback.
-
I don't think he meant that facetiously. He's one of the Boo language maintainers. I'd point out something cool about my language too if I was him. :D |
Beta Was this translation helpful? Give feedback.
-
@jnm2 @jnm2 @CyrusNajmabadi // 3.
if (conditional)
{
return false;
}
// 4.
if (conditional)
{
return;
} Option A would lead to: // 3.
if (conditional) => return false; // ISSUE: Does not behave like other arrow expressions.
// 4.
if (conditional) => return; // ISSUE: Does not behave like other arrow expressions and Option B would lead to // 3.
return if (conditional) => false; // Seems odd that return and false are separated
// 4.
return if (conditional); Option A causes a problems with a pre-existing construct and Option B has weird code separation. |
Beta Was this translation helpful? Give feedback.
-
It's not ambiguous either to the compiler or to anyone I have seen code, so my question still stands. ❔ |
Beta Was this translation helpful? Give feedback.
-
Why not just write:
if (conditional) { return false; }
if (conditional) { return; } You can already write a single-line-if that is unambiguous and easy to understand. It's not clear to why any new syntax would be required here. At best, the proposed syntaxes save 1-2 chars... that seems so completely unnecessary to support. |
Beta Was this translation helpful? Give feedback.
-
@MisinformedDNA Well, if you really want to show your intent, you could always just do this: if (condition) /*=>*/ statement; |
Beta Was this translation helpful? Give feedback.
-
I don't see anything about if (condition) { statement; } Is just as readable as if (condition) => statement; Furthermore, i would say that other forms are less readable. For example: return if (conditional) => false; Definitely less readable. 'returns' used to be unconditional, now i have to realize that i can flow past this depending on the conditional. Or return false if (conditional); Also less readable. I have to know the condition first to decide what to do. Making the condition then come after the flow just makes things harder to read IMO. This is similar to why linq declared variables up front, instead of doing it like SQL does. There's a certain flow of declarations and order of operations that C# tends to prefer that this goes very much against. |
Beta Was this translation helpful? Give feedback.
-
@CyrusNajmabadi There has been a lot of suggestions that gain only 1 character, but this one actually looses 3! The current syntax is even shorter than the suggested 😆 Also, if (condtion) statement;
if (condition)
statement; Are perfectly clear in intent. Adding |
Beta Was this translation helpful? Give feedback.
-
I'm sympathetic to the issue that arises with: if (condition)
statement; That said. I think there are perfectly good language features today that address it. No clue why someone people would have a style guideline that would prevent you from using that language feature. |
Beta Was this translation helpful? Give feedback.
-
Way, way, way back in the deep dark mists of time, I worked on a team that was adopting C# and .NET 1.1, moving from a combination of Visual Basic 6, VBA, PowerBuilder, and Delphi. (Possibly others.) At that time, and for that specific team, the members had the classic worry that
would be modified to
And that the code would therefore not work as it should. The team adopted a rule that explicit blocks should always be used. This was primarily driven by the lack of experience within the team, and it made sense for that team at that time. With improvements in IDEs (especially automatic code formatting), the advent of tools like R# and other analyzers (that will highlight dodgy code), and the widespread adoption of unit testing (which would typically catch issues like this), I think there's a case to be made for revisiting the guidelines. Coding standards are supposed to deliver value by guiding us towards known good practices. They're supposed to work for us, not the other way around. |
Beta Was this translation helpful? Give feedback.
-
With the new version VS it's even easier now because all I have to do is hit |
Beta Was this translation helpful? Give feedback.
-
DO wrap DO NOT use oh no. |
Beta Was this translation helpful? Give feedback.
-
Or DO wrap if embedded statement in braces DO NOT use oh no again. Design guidelines really should be enforced with analysers these days. And analysers can detect things like: if (condition) statement1; statement2; and flag it as a warning. This is always better than guidelines that need manual code reviews to enforce. |
Beta Was this translation helpful? Give feedback.
-
I don't think what I would put in my style guide is relevant to this discussion. But yes, I would treat them differently, but the other way around: Allow the variant with newline, disallow the one without newline, purely based on my personal stylistic preferences.
If I'm using ReSharper with some specific settings, then applying my preferences removes braces from
I think that's even worse. Consider this code: throw new Exception("Some fairly long error message explaining what the exception is about.", ex) if (condition); That condition is very important, but it's hidden at the far end of the line. This makes it easy to overlook, especially since it might require scrolling to see. In my opinion, syntax that hides the most important part of a statement is not good syntax. |
Beta Was this translation helpful? Give feedback.
-
To @HaloFour's and @DavidArno's point about analyzers, we actually https://github.com/DotNetAnalyzers/StyleCopAnalyzers with half the rules turned on. We set it up to flag incorrect indentation as a compiler error. So even beyond having to actively fight the IDE in order to make the syntax look ambiguous to humans, we would also instantly break the build. |
Beta Was this translation helpful? Give feedback.
-
@jnm2 Makes a good point about IDE's. Let's face it, if you're using C#, you're probably using Visual Studio, if not, some other intelligent modern IDE that has automatic indenting that will make you be constantly going out of your way to indent the code in a way that looks confusing. |
Beta Was this translation helpful? Give feedback.
-
I’d suggest followings @CyrusNajmabadi suggestion to just use the braces on the same line, because that is what I actually do. IMO if it’s short enough to be on the same line, it’s short enough that surrounding it with a couple of extra characters isn’t a problem. If adding a couple of braces makes the line too long, it is already too long to be a single line. Update the style guide, if the style guide is tooling, update the tooling. |
Beta Was this translation helpful? Give feedback.
-
I'd rather be able to use something like someBool ? return x() : return y(); |
Beta Was this translation helpful? Give feedback.
-
Err, @danielbls why not just write
which is already legal syntax? |
Beta Was this translation helpful? Give feedback.
-
I think Option C.4 as a limited case shorthand is nice. Only because there's not complex return types or expressions that might be confusing. return if (somecondition) isMet;
Console.WriteLine($"Condition is {isMet}"); // "Condition is false", tho for `return` carrying var is moot continue if (somecondition) isMet; or perhaps only in bool isExitCondition = true;
return if isExitCondition; continue if isExitCondition(); |
Beta Was this translation helpful? Give feedback.
-
It's frequent to have an
if
statement that contains a single statement. Due to design guidelines, we often end up wrapping those statements in braces. It would be great if we could find a way to remove the braces and still satisfy common guidelines.Previous proposals I've seen have tried to make this extend to multi-block statements like if-else or try-catch, but those have proven to have issues. Instead, this proposal is limited to single-line
if
statements that can be written without braces and also do not have anelse
statement.So the scope for this proposal is code that can be written as
but usually ends up formatted as
Here's some examples to consider:
Option A: Arrow expressions:
if (condition) => expression
Option B: Arrow expressions with conditional jumps/returns:
[jump] if (conditional) [=> expression]
Option C: Reorder the syntax:
statement if (conditional)
Option C may seem odd at first since the order is backwards from how we are used to, but the proposed C# 8
switch expression
also switched theswitch
keyword and the match expression, so there is some precedence for this.Option D: Reorder the syntax, but use
when
:statement when conditional
Given the similarities between Options C and other uses of the
when
keyword, a new option becomes intriguing:In conclusion, I think option D covers a simple but very common use case. Allowing us to condense our code from
to
Someone will want to expand this to cover
else
blocks, but I don't see that as stictly necessary. In fact, if someone really wanted anelse
block, and all other options didn't meet their needs, they could easily use the rule above to create a fauxelse
just by doing:Thoughts?
Beta Was this translation helpful? Give feedback.
All reactions