dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.93k stars 4.02k forks source link

Elimination of the use of semicolon at the end of every statement in C# 7 #9793

Closed josejmoran closed 8 years ago

josejmoran commented 8 years ago

Version Used: C# 6

Steps to Reproduce: We all have to put the ; at the end of every statement. The compiler complain if we don't. Could it be possible to eliminate the need of adding the semicolon?

It is a dramatic request, but I think at this point we can get rid of it. The compiler knows when we missed it, it give us an error. Since it knows, could the IDE analyzer add it automatically or better just not expect us to type it anymore. F# do not have it, Swift do not have it. C# can get rid of it :)

Expected Behavior: Love to see this: Console.Write("No more semicolons, yeah!!") Actual Behavior: Console.Write("Hating the semicolon at the end, yeah!!");

alrz commented 8 years ago

Dup of #5355 #8071 #2974.

DavidArno commented 8 years ago

@alrz, #2974 is unrelated to this. However it is indeed a duplicate of #5355 and #8071

DavidArno commented 8 years ago

@alrz,

Since you seem to be the font of all knowledge on previous requests, is there one specifically related to reducing the noise around read-only properties already, ie suggestions for SomeProp { get } or SomeProp get; ?

alrz commented 8 years ago

Since #8071 is itself closed as a duplicate of #2974 per this comment, so no, it's directly related. I mentioned it for the sake of discussion on that thread.

I'm not "font of all knowledge on previous requests", it's the god-given gift of ability to search issues.

For that particular novel idea to save one signle character you can refer to #8985 and this comment. Also it wouldn't work out well when you want to write { get private set }. Having two identical syntaxes for a feature without any additional gain doesn't seem to be a good idea though.

DavidArno commented 8 years ago

@josejmoran,

There are languages that are designed to work without semicolons. There are languages that mandate them. Then there are languages that open up a whole world of nasty "gotchas" when they make them optional as it leads to inconsistent syntax. Getting rid of semicolons completely isn't feasible, so if you want to use C#, unless you are prepared to introduce problems, you are stuck with them.

DavidArno commented 8 years ago

@alrz ,

I wouldn't want to write { get private set }, or { get; private set } as that would allow a class to sneakily modify parameters and thus break the immutability pattern. The fact that @gafter doesn't see the benefit of reducing one character of noise doesn't surprise me, but thanks anyway.

vbcodec commented 8 years ago

Maybe there is need for totally opposite option: automatically add semicolon to the code by editor (autocomplete). So when you press ENTER, then editor add semicolon at end of line. One keystroke less per line.

Partially eliminate semicolons probably do not make sense, as it will spark lot of confusion.

DavidArno commented 8 years ago

@vbcodec,

That makes a lot of sense.

alrz commented 8 years ago

@vbcodec Then you wouldn't be able to format chained methods like this,

var q = list.Where(...) // oops, semicolon inserted
    .Select(...)
Thraka commented 8 years ago

@alrz @vbcodec Since this would be an editor change, if you started the next line with a . the editor should automatically erase the previous semicolon and continue.

However, with how close the ; and ENTER keys are, I don't know how much time this actually saves and thus becomes a useful feature.

alrz commented 8 years ago

@Thraka It's not just . what about ? and pretty much everything else. because C# doesn't give a damn about whitespace at all. Perhaps you should specify in what situation it should insert a semicolon. That becomes rather complicated just to save one single god damn keystroke.

Thraka commented 8 years ago

@alrz I agree, I don't think it's really useful at all. I'm just helping @vbcodec's flesh out his suggestion with ways to detect intent. So it would include any sort of character that would continue the line if the ; was missing.

josejmoran commented 8 years ago

Swift language do not have semicolons. It proves that C# 7 can get rid of it completely. I vote for having the semicolon completely eliminated.

AdamSpeight2008 commented 8 years ago

@josejmoran wrote: Swift language do not have semicolons. It proves that C# 7 can get rid of it completely.

It does not prove anything in context to C#. It only proves Swift doesn't require semicolons.

May I suggest that you get a copy of the C# Language Specification. The elimination of semicolons would lead to ambiguities, or incorrect evaluation to what the coder intended. What was perfectly valid and compiling code,

jaredpar commented 8 years ago

Thanks for taking the time to file this. It does look like this is a dupe of #5355 and #8071. Resolving and letting discussion continue there.

DaveVdE commented 8 years ago

Where's Hejlsberg when you need 'm.

forki commented 8 years ago

In F# and swift semicolons are optional. But they are required if you are doing two expressions on the same line (see https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html)

The pure fact that swift and F# make semicolons optional doesn't prove anything for C#. There are many other things that may break syntax ambiguities (like being whitespace significant ;-))

AdamSpeight2008 commented 8 years ago

@DaveVdE Doing better things with his time.

oxysoft commented 8 years ago

I 100% support optional semicolons.

Modern compilers don't need semicolons to understand the code anymore. Whenever somebody gives reasons on why we need semicolons,, it's always a mix of semi-valid and bullshit reasons. (mainly bullshit reasons though) Plenty of languages cleverly implement optional semicolons without causing any ambiguity.

For those who think that we want optional semicolons to save a keystroke, you are so far gone that I'm not even going to attempt to explain why one might want optional semicolons

vsg24 commented 7 years ago

I would love C# without semicolons.

asydneylover commented 7 years ago

yep, really love C# without semicolon. And that is one of the key factor to differentiate between C# and Java :)

mrkaspa commented 7 years ago

Love that too

DrSensor commented 6 years ago

I hope they give us official C# linter that have automatic semicolon insertion (ASI) like in eslint

zbyt3s commented 6 years ago

The only possible option is all of you are stoned and wanting to give your opinion on how to make a powerful, accessible and great programming language full of bugs like JavaScript ;

zbyt3s commented 6 years ago

We're now ready to get rid of semicolons.....

Whatta hell?? speak for you dude

oxysoft commented 6 years ago

@zbyt3s What makes you think that the implementation would be as naive as Javascript's? Kotlin, Scala, and Groovy all got rid of semicolons with very very few gotchas. Compilers are smart today, and can look at the lines that come after to infer what the programmer meant with great accuracy.

zbyt3s commented 6 years ago

@oxysoft It's really not about being "conservative" at all costs.. I think C # should maintain a programming style typical of C languages, those which wrote history of informatics..

However i think it would create bunches of doubts and issues to programmers, it would create problems nesting code blocks et cetera, C# is great, what's the problem about line terminators?

(;) is surely not fundamental as "{}", but there is really not the need to eliminate them.

I would happily accept IntelliSense completing statements automatically however..

CyrusNajmabadi commented 6 years ago

What makes you think that the implementation would be as naive as Javascript's? Kotlin, Scala, and Groovy all got rid of semicolons with very very few gotchas.

Note: This is a difficult problem and can be significantly limiting for future language design.

Let's take, for example this case:

  1. Should automatic-semi-colon insertion be allowed after a return-statement if it's unambiguous what is meant.

i.e. if i have:

if (x) 
    return

if (y)
   // ...

In principle, this seems reasonable. 'if' cannot follow 'return' and 'return' was not given an expression or a semicolon.

However, if you do this, it means in the future you could not add a hypothetical 'conditional returns' feature. i.e. imagine if the language wanted to let you say:

return if(y)

Note that this is not out of the realm of possibility. Customers have asked for this precise feature to make performing return-style checks very lightweight and simple.

However, now, the original code changes meaning. 'return' was 'followed' by 'if', meaning that you have a deep problem deciding what to do. If your rule is "only ASI when encountering a token you don't know what to do with" then you should parse this out as "return if". If your rule is "don't allow the original code because there was a return", then you have Javascript, and its awful behavior where adding a return can change the semantics of your code. i.e. the difference between:

return { 
   x: y
}

vs

return
{
x: y
}

(yes, both of those are legal, but have different meaning).

If you don't do either of those, then you have some new rule, which is: speculatively look forward some distance, figure out later on that things have gone wrong, then go back to try to figure out where you should have done ASI. And now it's completely confusing.

--

So this feature is not a slam dunk. It's hard to do well, and it's extremely hard to do in a manner that does not box you in syntactically in the future.

jmarolf commented 6 years ago

I would happily accept IntelliSense completing statements automatically however..

this seems like a reasonable path forward. If the formatter had an option to aggressively auto-insert semicolons where they were missing I wonder what the experience would be like.

oxysoft commented 6 years ago

@CyrusNajmabadi It seems quite clear to me that even if a return if(y) statement was added, the code below is NOT meant to use it.

if (x) 
    return

if (y)
   // ...

It isn't ambiguous in any way, 'return' is indented and 2 lines above. Such ambiguity only exists for a dumb compiler, and it's entirely possible to write a smart one that is able to follow the intent. Sure, there is an argument to be made about creating dependency between the formatting of the code which historically has only existed in regards to spaces but not indentation and line breaks in C-like languages. However it doesn't really have to care about indentation, only line breaks and spaces in this case.

It would be reasonable in my opinion to expect a return if feature to force the 'if' to directly follow after the 'return', separated by one space or any number of space so long as it is clear what the intent is. (that is, it should be on the same line at the very least.)

CyrusNajmabadi commented 6 years ago

It isn't ambiguous in any way.

Of course it's ambiguous. :) You have "return" followed by "if". that's exactly what hte grammar of "return if" would start with.

It isn't ambiguous in any way.

This is also the javascript interpretation, which is loathed by many people, (including myself).

According to JS, it's completely unambiguous that

if (x) 
    return

{
x: y
}

Is different from

if (x)
    return {
       x: y
     }

And yet, people get bit by entering a newline here over and over again. They say "things aren't whitespace sensitive, and i'd like my return expression on the next line" and they add a newline, and bam, their program breaks.

Super common case:

return Foo(a, b, c);

Oh... now i want that to be:

return 
    Foo(a, b, c) ||
    Bar(a, b, c) ||
    Baz(a, b, z);

This is now completely different.

--

It would be reasonable in my opinion to expect a return if feature to force the 'if' to directly follow after the 'return', separated by one space.

And that is now completely unlike C#. C# has never ever ever mandated a single space between any keywords. Indeed, the point has been that is' whitespace insensitive. Between tokens, 1 space versus N doesn't matter.

If you now require this you are very much changing the feel of the language, and you are doing precisely what i said from the beginning: you are putting significant design constraints on the language for how you make syntactic changes in the future.

sharwell commented 6 years ago

@oxysoft @jmarolf If we implemented #18104 I believe you would be very happy with the result. I have used this behavior in an experimental setting and it felt remarkably natural.

oxysoft commented 6 years ago

I am not well versed in JS, but what would that block be doing if it wasn't returned? Create an object and do nothing with it?

{
x: y
}

Again, it's quite clear to me that it should be returned whether it is 2 lines below or on the same line as the return, and a good compiler could figure this out as well.

Your second example doesn't seem to pose any issue to me.

return 
    Foo(a, b, c) ||
    Bar(a, b, c) ||
    Baz(a, b, z);

Because C# is statically typed, the compiler knows ahead of time what the method should return, and it also knows that nothing can occur after a return. It should therefore compile when the return type is void or it matches the return-type of Foo, Bar, and Baz. An argument could be made that it could create confusion if you mistakenly declare the return type of that method as one or the other and you don't notice it until it's too late. I think it's fine if the return type isn't void, but if it is void, then perhaps an error should be spat out by the compiler since code after returning void makes no sense anyway.

Things get interesting if you have the following...

...

if (x)
    return 
        Foo(a, b, c) ||
        Bar(a, b, c) ||
        Baz(a, b, z);

x = z
// Other stuff..

...

At that point, it's not particularly clear at first if we should return void or the result of the lines below. However, I believe we can apply the same clever line of thinking as before, and infer the meaning from elsewhere such as the return type of the method. It may be worth looking at what other languages like Kotlin do with something like this.

oxysoft commented 6 years ago

@sharwell I do not use Visual Studio so this does not apply to me. Jetbrains has already figured out this stuff years ago so this is not a problem. For me, the issue with semicolon is not a typing one but rather a visual one.

CyrusNajmabadi commented 6 years ago

I am not well versed in JS, but what would that block be doing if it wasn't returned? Create an object and do nothing with it?

{
x: y
}

It's simply a block with a labeled statement. Totally legal.

CyrusNajmabadi commented 6 years ago

Because C# is statically typed, the compiler knows ahead of time what the method should return, and it also knows that nothing can occur after a return.

I can state, fairly confidently, that c# will never take semantic-directed parsing. This makes things even weirder. Because now, you're saying that the meaning of hte same syntax would be different depending on if it was a void-returning or non-void-returning function.

CyrusNajmabadi commented 6 years ago

whether it is 2 lines below or on the same line as the return, and a good compiler could figure this out as well.

Again, this is now saying: c# is whitespace sensitive. Something it has never been before. Indeed, people have grown accustomed to being allowed to place whitespace all over the place. It's one of the core ways that people customize and personalize their code.

oxysoft commented 6 years ago

I also believe C# will never throw semicolons in the trash can, there's way too much history behind it and it will most undoubtedly break previously valid code. I'm just going back and forth for the sake of the argument, and I also would love to write clean semicolon-less C#, even if I know it will never happen in a million years.

CyrusNajmabadi commented 6 years ago

then perhaps an error should be spat out by the compiler since code after returning void makes no sense anyway.

You're presuming that one of hte two interpretations of the code is not legal. The problem occurs in practice because both interpretations lead to legal code.

This means you might end up ending up in a world where code meaning changes between releases. Which is something completely unacceptable for many customers.

CyrusNajmabadi commented 6 years ago

I'm just going back and forth for the sake of the argument, and I also would love to write clean semicolon-less C#

I think c# might adopt something like this. I was only making the point that is' not something simple to do, and that solutions in this space come with many drawbacks, including, but not limited to:

it can be significantly limiting for future language design.

oxysoft commented 6 years ago

It's definitely not simple to do, but I think the fact that many modern languages have adopted it without causing as much trouble as it has in JavaScript is proof that it can be done in an effective manner that does not create ambiguity, nor restrict future language design as can be seen with many of those languages which keep flourishing and integrating new syntactic sugar and/or language features year after year.

CyrusNajmabadi commented 6 years ago

I don't think we have any existence proofs that the above is true. Yes, languages have adopted it. But it may absolutely have restricted language design. Note: that restriction may have been completely acceptable for those languages. But htat doesn't mean those restrictions would be ok for this language. The patterns, practices, history, and expectations are completely different between the two.

--

For example, as evidenced by our back and forth on 'return if', i would be skeptical of the language ever adopting a policy that mandated a specific whitespace pattern between tokens. That would feel extremely odd for C# and would really be out of line with literally 100% of the language prior to that point. However, had C# gone that route in V1, then the conversation could be very different.

It would be the first case of the core language mandating trivia style, when C# has always been opinionated that is has no opinion here and leaves it to the individual dev or team to make those choices.

josejmoran commented 6 years ago

We end each line with <Enter>, it will be feasible to just take that as the terminator for the line statement.

CyrusNajmabadi commented 6 years ago

We end each line with , it

Sorry, something seems to be cut off. What are you saying you end each line with?

josejmoran commented 6 years ago

We end each line with Enter character, it will be feasible to just take that as the terminator for each line of code instead of the semi-column therefore rendering it unnecessary.

CyrusNajmabadi commented 6 years ago

We end each line with Enter character, it will be feasible to just take that as the terminator for each line of code

So users could not use enter within any expression? Because it was now the line terminator? That would definitely feel very un-c#-like...

josejmoran commented 6 years ago

Most of the code we write is enclosed in {}. We don't add ; after the closing parenthesis. We can make the same arrangement for each line of code. It just feels like why do we have to add this ; at the end of each line. Why? There is a rule that requires it, lets just get rid of the rule.

CyrusNajmabadi commented 6 years ago

It just feels like why do we have to add this ; at the end of each line. Why?

To make it clear how your statements are separated. Otherwise, you can end up in ambiguous situations that really confuse people.

Note: this is what you get in javascript in several cases, and it's something that has messed up and upset lots of people, precisely because they do not want to allow "end[ing] each line with Enter character".

There is a rule that requires it, lets just get rid of the rule.

The rule is "the grammar". And removing statement ending semicolons from "the grammar" has a lot of potential consequences to how code is interpreted, and how the language feels and behaves. as i mentioned above, it also has a significant impact on how you can change the language as you move forward.

beppe9000 commented 5 years ago

what if you change the line separator to CR+LF? vb.net on steroids...

JeroMiya commented 5 years ago

I don't support optional semicolons in languages. I prefer syntax without semicolons, and I'm OK with languages that use semicolons, but languages that have optional semicolons, I do not like. Readability suffers when there are multiple ways to do the same thing. Sometimes that's worth it. In this case it is not, in my opinion.