Skip to content
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

Meta-issue for discussion of the proposal to make semicolons after statements optional #30347

Closed
leafpetersen opened this issue Aug 7, 2017 · 156 comments
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion

Comments

@leafpetersen
Copy link
Member

This issue is to provide a forum for community discussion and feedback related to the proposal to make semicolons optional after statements.

This entry will be updated when a proposal is available.

cc @munificent @eernstg @floitschG @lrhn

cc @Hixie

@leafpetersen leafpetersen added area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion labels Aug 7, 2017
@brianegan
Copy link

brianegan commented Aug 8, 2017

Just my 2 cents, but coming from a JS / Android background, I'd love either "Semicolons - YES" or "Semicolons - NO".

I do not think OPTIONAL semicolons are healthy for a development community for two reasons:

  1. It will lead to needless bikeshedding. Just witness / read up on the endless debate in the JS community over whether or not to use them. So many hours wasted over something purely stylistic. These debates do not help us solve actual problems.
  2. Additionally, it will make reading code harder for beginners, because it will introduce a stylistic distinction that might not be as easily understood by newcomers.

To keep an open mind, I'd love to hear more about the reasoning in support of optional semicolons. Do folks feel it will help adoption? Is it a stepping-stone toward a Dart v3 w/o semicolons?

@Hixie
Copy link
Contributor

Hixie commented Aug 8, 2017

The bikeshedding in the JS community isn't over something purely stylistic. Semicolon insertion in JS (and some other "optional semicolon" languages like Kotlin) can have very dramatic effects on the semantics of the code. For example, consider:

// Javascript
function test() {
    return 1 + 1
             + 2
             + 3
}

console.log('Hello, world! ' + test());
// Kotlin
fun test(): kotlin.Int {
    return 1 + 1
             + 2
             + 3
}

fun main(args: Array<String>) {
    println("Hello, world! ${test()}")
}

What do you think they print?

@Hixie
Copy link
Contributor

Hixie commented Aug 8, 2017

(I am reserving judgement on the issue when it comes to Dart until there's a concrete proposal.)

@sethladd
Copy link
Contributor

sethladd commented Aug 8, 2017

Make it an error to have statement continuations after the return line. Also, I'm curious if there's actually a problem here, given what go, kotlin, and swift have been doing. Do they report this as a static warning or error?

I am not worried about "two ways to do it", there are infinite ways to do most formatting and conventions. I am confident that the combination of automatic formatters and style guides (both global and local per-team) will create cultural norms here.

@brianegan
Copy link

brianegan commented Aug 8, 2017

@sethladd Before we talk about all the tools that could be built to support this, could you maybe just elaborate a bit about what you see as the user benefit? How will this help us write better programs as a community? What "user need" is it targeting / solving?

To be clear: I prefer languages without semi-colons, but I just don't quite see what this will add to the Dart community or how it will help the ecosystem overall, and that's what I'm trying to understand a bit.

I'll await the proposal to see if it answers those Qs :)

@sethladd
Copy link
Contributor

sethladd commented Aug 8, 2017

Modern languages are generally believed to be less boilerplate, more terse, and including language features working for you. For example, type inferencing is the language working for you. We could force you to right type annotations everywhere, or we can say "in many cases, we can infer it for you". Auto-inserting punctuation is another way the language can work for you. Also, there's an element of being seen as a light-weight, modern language and staying competitive. The trend in languages was to go to var, to go for closures, to go for => functions, and now to go for implicit semicolons (done right, of course).

@Hixie
Copy link
Contributor

Hixie commented Aug 8, 2017

The code above is valid in Javascript and Kotlin respectively. (But the important question to me is, can you guess what they print?)

I think "make it an error to have statement continuations after the return line" is a perfectly valid part of a complete proposal, but I'd need to see the complete proposal before I could really say how valid it is.

BTW, omitting punctuation isn't new. Perl, Fortran, even COBOL all had stuff like this. Lisp didn't even have semicolons. I would hardly say it's a sign of a modern language.

@sethladd
Copy link
Contributor

sethladd commented Aug 8, 2017

I would hardly say it's a sign of a modern language.

Re-modernizing? But yes, good point, plenty of languages pioneered here.

@Hixie
Copy link
Contributor

Hixie commented Aug 8, 2017

In fact, Perl went even further and allowed you to omit the (/) around function arguments, if you want to really have the language "work for you". You can write entire programs in Perl using nothing but a-z and whitespace. I'm not sure I would take that as a point in favour of the language, though. The work Perl does for you when writing the code is work you have to pay back in spades when reading the code, to the point that Perl has often been referred to as a write-only language. Readability is infinitely more important than writeability.

@ds84182
Copy link
Contributor

ds84182 commented Aug 10, 2017

So there are several problems that arise if Dart removes the semicolon requirement:

With semicolons:

print("hello");
() { print("goodbye"); };

Without semicolons:

print("hello")
() { print("goodbye") }

The first example would just print "hello", the second example could either print "hello" or throw an error, depending on how it's interpreted by the parser.

This can become worse if someone does this:

returningPrint() => print
() { print("goodbye") }

Now, instead of the function returning print the function tries to return the result of print(), which isn't a valid function call.

There would be a lot of ambiguity introduced by closure syntax... who says it's a call + block or a closure?

@sethladd
Copy link
Contributor

How do swift, go, and kotlin handle these cases?

@Hixie
Copy link
Contributor

Hixie commented Aug 10, 2017

Go has a crazy syntax for lambdas which is whitespace-sensitive (you can't put a line break after the arguments before the return type, or some such). They also have a reserved word before the lambda which disambiguates between closures and calls.

Swift and Kotlin use braces for closures. I haven't quite figured out the syntax exactly. Kotlin, as previously mentioned, makes choices that make its semicolon-insertion confusing and bug-prone.

@zoechi
Copy link
Contributor

zoechi commented Aug 16, 2017

If there is a simple way to get rid of all ambiguities, then getting rid of semicolons would be great of course.
If getting rid of ; hurts for example autocompletion, I'd rather keep ;.
Making ; optional only for most cases seems more like an approach to appeal to JS developers to me, like Dart tried at the beginning with it's optional types, to then later move to strong mode because the original approach limits language development and most developers prefer good feedback from the tools anyway, which in the end could mean optional ; might hurt more than it helps (as already hinted to by @brianegan)

@munificent
Copy link
Member

munificent commented Aug 25, 2017

Just my 2 cents, but coming from a JS / Android background, I'd love either "Semicolons - YES" or "Semicolons - NO".

We would make semicolons optional mainly to support:

  1. Migrating existing Dart code that contains them.
  2. Code that is mechanically generated by tools.
  3. As an input to an automated formatter which would then remove them and replace them with whitespace as appropriate.

Idiomatic Dart code would not contain semicolons, "Effective Dart" would tell you to omit them, and dartfmt would probably strip them. Note that Ruby, Scala, Go, Lua, and Python all allow semicolons and yet semicolons have not infested their ecosystems. :)

@JoseRFJuniorLLMs
Copy link

yes god

{
usePushEach: true
},

@Kirrrr
Copy link

Kirrrr commented Feb 7, 2018

Excuse me my freshman impertinence but I want to place some biased yet sincere questions here.

Isn't semicolons at the end of statements a part of solid complex language syntax?
Doesn't omitting of semicolons lead to need of serious changes in language syntax to keep it ok?
Isn't semicolons a mean to achieve sturdy and transparent code structure? Is that syntax overhead really hard to bear?
Isn't it pretty strangely to draw parallels between Dart and other languages with significantly different syntax?
Is current Dart syntax really ready for omitting the semicolons without any damage to whole project?
What is the real positive impact of omitting of the semicolons besides of somebodie's attitude? Guys, lets take a good experiense from Assembler language and shorten all keyword to 3-4 letters, hm? Or lets declare war to colons and points because there are so many of them in code.

(sorry for clumsy English)

@zoechi
Copy link
Contributor

zoechi commented Feb 7, 2018

@Kirrrr I also don't mind writing them, but if the Dart team sees a good way to get rid of them without causing serious downsides, I don't see why they shouldn't make an attempt.

I think non-nullable-, union-, immutable- types and extension methods have much higher priority, but that doesn't mean I'm against getting rid of ;.

@munificent
Copy link
Member

Good faith questions are always welcome. :)

Isn't semicolons at the end of statements a part of solid complex language syntax?

Nope. It's an arbitrary choice. Some languages have nice, clean, solid syntax but no semicolons (Lisp, Smalltalk, Python). Perl does require semicolons but is notoriously tricky. Complexity is never a goal, it's a cost we pay to attain other goals. Simplicity is the goal.

Doesn't omitting of semicolons lead to need of serious changes in language syntax to keep it ok?

It depends on the language and the rules you use to treat newlines as significant. If we do it well, no. We wouldn't make them optional if it caused significant changes to the way people write their Dart code.

Isn't semicolons a mean to achieve sturdy and transparent code structure?

Not really. It's just a character. There's nothing magical about ";" compared to "\n", ".", etc.

Isn't it pretty strangely to draw parallels between Dart and other languages with significantly different syntax?

Some of the languages with optional semicolons are pretty similar to Dart syntactically — Swift, Kotlin, and Scala in particular.

Is current Dart syntax really ready for omitting the semicolons without any damage to whole project?

Yes. It's a pretty small change. Go made semicolons optional after the language was in wide use without any major problems.

What is the real positive impact of omitting of the semicolons besides of somebodie's attitude?

Users choose products for both technical and emotional reasons. Programming languages are visual products (for most users) and the visuals matter. If most of our users find that Dart looks nicer and is less error-prone without requiring explicit semicolons, it's a win.

@Stargator
Copy link
Contributor

We would make semicolons optional mainly to support:

I would recommend either Semicolons must be used or no semi-colons. If we are going to take the effort to change the language regarding this, it needs to be clear and not a patch intermediate step.

Optional semi-colons serves no practical matter nor resolves a problem. It would only exist as a migration path and, if so, thus should be avoided as it easily could be left in the SDK for years due to debate.

The Dart language isn't against introducing breaking changes (see: Dart 2.0). So again, the decision should be either with semi-colons or no semi-colons.

In my opinion, I say leave the semi-colons in. It fits Dart's intention of not being surprising to developers.

@daveob
Copy link

daveob commented Mar 26, 2018

Coming from hobbyist languages like BASIC and Lua, I would love to see Dart get rid of (or at least make optional) the ending semi-colon. For me, it makes the language appear less fussy and more readable.

@munificent
Copy link
Member

I would recommend either Semicolons must be used or no semi-colons. If we are going to take the effort to change the language regarding this, it needs to be clear and not a patch intermediate step.

Optional semi-colons serves no practical matter nor resolves a problem. It would only exist as a migration path and, if so, thus should be avoided as it easily could be left in the SDK for years due to debate.

Well, migration is a problem. :) Also, allowing semicolons makes things easier for tools like code generators that produce Dart source code and don't want to have to fuss with newlines.

Python, Ruby, Kotlin, Scala, and Swift all allow semicolons. Despite that, they all have consistent clean ecosystems where semicolons rarely appear in user code.

@Stargator
Copy link
Contributor

Well, migration is a problem

Migration is always a problem (see Dart 2.0). But should mean making it optional. Does the language really need to make semicolons optional? No, it doesn't.

The language is best when designed for the developer's use as a consumer of the API. Whether tools like semicolons is irrelevant.

I think the semicolons should stay and not be optional. It makes the language easier to understand especially when different examples of the code are given. And that is Dart's best feature, not being surprising to the developer and using tried and true concepts.

Optional semicolons causes more confusion for new users as well as teams trying to come to a standard. The Dart Style Guide would have to choose a side and that'll decide how most users go.

@brianegan
Copy link

brianegan commented Mar 27, 2018

I was on the fence about optional semi-colons, but have been persuaded the arguments made above: If the Dart Style Guide recommends no semicolons and dartfmt could automatically remove them, I'd be a happy camper. Once you get used to writing code without semicolons, it's hard to go back. Making them optional seems to have legit use cases.

Overall, I think it's a good thing if peeps go with the Dart Style Guide out of the box! The fewer style discussions we have the more time we have to write our apps. As a bonus, it makes it easier is to read through other code bases as well :)

@Hixie
Copy link
Contributor

Hixie commented Mar 28, 2018

I think it's impossible to have an informed opinion without knowing what the concrete proposal is. If it's like more like JavaScript or Kotlin, where you can't tell at a glance what the code does, and where in some common cases you can write code that actively looks different than what it does, then it's probably a mistake. If it's more like Lisp, where there's no ambiguity, then it's probably fine. In between these poles are languages like Pascal, where semicolons are optional in certain cases and must be omitted in certain cases and required in others, but that doesn't gain you much (maybe slightly cleaner lambda block syntax though the => syntax in Dart makes that moot).

@kuashe
Copy link

kuashe commented Apr 7, 2018

Making ; optional only for most cases seems more like an approach to appeal to JS developers to me

@zoechi I think it would be regrettable not to appeal to JS developers , especially for those looking for an alternative to Node.
Has pointed out by @brianegan , after not using semicolons for a while it's really hard to go back to a language using them . Go doesn't use them and it makes the code incredibly simple to read , it seems like the community really enjoy it.

Using ; everywhere makes Dart feel very much like Java, which is regrettable because Dart is in general less verbose than Java.

@Stargator
Copy link
Contributor

Using ; everywhere makes Dart feel very much like Java, which is regrettable because Dart is in general less verbose than Java.

I like that feeling, though 🤔

@agrosner
Copy link

Semicolons are really just noise. If you need to write something like:

print("hello");
() { print("goodbye") }

then there is something else wrong than just needing semicolons.

IDE can warn you in instances where you might get tripped up, but overall, removing semicolons is much cleaner. Coming from Kotlin, swift, JS, I keep forgetting to put in ; which is annoying and requires a little bit more of thought.

I mean the examples listed above are valid, however given a strong direction on what it prints just requires a little more learning.

function test() {
    return 1 + 1
             + 2
             + 3
}

if an operator is listed on the next line of a return statement, dart should just collect them or just make it an error to place an operator on the next line as first statement.

@pitoszud
Copy link

It is uncommon to see semicolons in the code written by developers who switched from Java to Koltin, even among those who coded in Java for years (including myself). An exception may be one-liner lovers, who like e.g separate a statement and print.
(Enums are the only exception as far as I'm aware)

In Flutter I often make mistakes by either not adding the semicolon or adding it where it is not necessary - examples below

Example 1

 CupertinoPicker(
        itemExtent: 32.0,
        onSelectedItemChanged: (selectedIndex){
          print(selectedIndex)    // compile error 1
        },
        children: menuItems.map((value) => Text(value)).toList();  // compile error 2
      ),

Example 2

 final List<Text> _childrenList = menuItems.map((value) => Text(value)).toList()    // compile error 3

If you implement this right, you unlikely to break anything by making this optional and I'm pretty sure that majority of developers will not be using semicolon inference if it becomes an optional language feature.

@larsblumberg
Copy link

I'm on my first day with Flutter/Dart, pleasant experience, except: I come from Swift, Kotlin, Python, JavaScript. Semicolon are something of last century. Please, please dear Dart team: make the semicolon optional. We don't need them. Listen to your users to

1.) make sure that Flutter/Dart gets a broad adoption so that Flutter/Dart doesn't drown away like other Google projects
2.) show your user base that we can trust in your willing to innovate mobile app development.

@matejthetree
Copy link

Is there any insight from the dart team on how do you see this proposal ?
Thank you

@kasp1
Copy link

kasp1 commented Sep 10, 2019

+1 for NO semicolons

For some reason, I've got used to no semicolons in JS very easily. But I find it much harder to get used to semicolons in Dart again.

@munificent
Copy link
Member

munificent commented Sep 11, 2019

Is there any insight from the dart team on how do you see this proposal ?

This issue isn't a proposal, as much as it is an indication of desire. Wanting to have a roof over one's head is a valid desire for a solution to a real problem. But it's not equivalent to an architectural blueprint of a specific home someone could build. :)

I spent a lot of time earlier this year and last year working with the rest of the language team to design a concrete proposal that would satisfy this desire. So far, we have yet to figure out a design that we feel comfortable adding to the language. This is a particularly hard problem in Dart because of the syntax it already has. Most other languages with optional semicolons were either designed that way from the start (Ruby, Python, Scala, Swift) or had the luxury of starting from very simple grammars (Go). Dart's C/Java/JS-esque syntax is neither. It's a very dense syntax that overloads many tokens to mean different things in different contexts and doesn't rely heavily on keywords. That makes it really hard to determine which newlines are meaningful.

I wrote up a summary of my investigation so far here. We haven't given up hope, but we are tabling it for now to focus on more impactful features like non-nullable types and extension methods.

@dancojocaru2000
Copy link

I am unable to read the whole thread, but I will address some concerns that I saw popping up often.

An example of ambiguity was this:

main() {
  someVeryLongIdentifier.anotherVeryLongOne
  andAThirdVeryLongIdentifier
}

The concern would be that this could be either 1. calling the getter anotherVeryLongOne from someVeryLongIdentifier and then calling the getter/ accessing the variable andAThirdVeryLongIdentifier, or 2. declaring the variable andAThirdVeryLongIdentifier of type someVeryLongIdentifier.anotherVeryLongOne.
I see this as a real non issue. Just don't allow a newline between the type and the identifier when declaring a variable. That way, the code above would be 1., while this code below would be 2..

main() {
  someVeryLongIdentifier.anotherVeryLongOne andAThirdVeryLongIdentifier
}

Furthermore, using quite simple code analysis, once can figure out if someVeryLongIdentifier.anotherVeryLongOne is a type or returns a type in order to allow declaring a variable.

A lot of the issues can be actually solved by adding a continuation character in order to clarify ambiguity when the statement on the current line is valid. For example, the following code...

int something() {
    return 1 + 1
           + 1
           + 1
}

would just return 2, with a warning that the lines after the return are unused. In order to return 4, assuming that the character chosen for line continuation would be \, we could write the function in the following way...

int something() {
    return 1 + 1 \
           + 1 \
           + 1
}

or in the following way (since 1 + 1 + is an incomplete statement, it would require looking on the next line to complete it)

int something() {
    return 1 + 1 +
           1 +
           1
}

@dancojocaru2000
Copy link

Another concern was method chaining. The following example was given:

 var buffer = StringBuffer()
   ..write(copyright)
   ..writeln()
   ..writeln("// GENERATED FILE, DO NOT EDIT!")
   ..writeAll(generatedMethods, "\n");
 var text = buffer.toString();

The problem would be that, theoretically, StringBuilder() is a complete statement, therefore a semicolon would be automatically inserted after it, breaking the code on the next line.

In this case, some simple smarts is needed. You can't ..methodName() on nothing. Therefore, on encountering ..write(copyright), Dart will simply go "alright, I need the previous line" and remove the implied semicolon from it.

@lrhn
Copy link
Member

lrhn commented Sep 15, 2019

There are a large number of examples where grammar rules, type analysis or common sense can tell you that the next line should be a continuation of the previous one. The trick is that we need to figure this out while parsing (which pretty much precludes type analysis) and in a way so that we can supply help while the code is being written, and that we must define a finite (preferably small and consistent) set of rules that covers all these examples.

A 50-point set of exceptions is not good for users trying to predict what their code means. Simple rules like "if the following line can continue, then it will" is dangerous, so is "if the following line cannot continue, then it won't" because either will require the author to understand all the fine points of the Dart grammar before they know whether they can omit a semicolon or not.

Not saying that the suggestions here are not reasonable, just that they, by themselves, are not enough.

@munificent
Copy link
Member

Just don't allow a newline between the type and the identifier when declaring a variable.

The main problem with this is that there is actually a significant number of cases in the wild where this already happens. People do end up with fairly long types (usually function or generic types) and variable names sometimes and wrapping does occur. Breaking that code would make this a harder feature to ship.

Furthermore, using quite simple code analysis, once can figure out if someVeryLongIdentifier.anotherVeryLongOne is a type or returns a type in order to allow declaring a variable.

We don't want to rely on type analysis to parse. That would mean the grammar isn't context free, which is widely considered a bad idea in programming languages. C and C++ are famously not context free and it causes no end of headaches. Search for "most vexing parse" for one example.

In particular, consider that dartfmt, by design, does not do any type analysis. This is important because we want to be able to format code that may have type errors or that imports other files that aren't available. If you need types to parse, it means dartfmt can no longer do that.

Your other points about using the trailing token or the first token on the next line to tell when to ignore newlines are correct. That's what all the proposals we've considered do, and those cases aren't particularly problematic. :)

@Stargator
Copy link
Contributor

Stargator commented Sep 18, 2019

@munificent for sharing your experience investigating this. I am not a language expert.

I do wonder which is easier to implement: remove semi-colons or having them optional?

I would imagine the former is easier as the latter would require additional work like tracking where to insert a semicolon and doing that. However, the former would still require determining what is a new statement or end of a statement.

I ask cause my preference is the former as I do not think optional semi-colons provide value, if they are optional, so they might as well not be needed.

@lrhn
Copy link
Member

lrhn commented Sep 18, 2019

I do wonder which is easier: remove semi-colons or having them optional?

To a compiler, it's exactly the same. If all semicolons are optional, then the language grammar has to work without any semicolons, so it has to be able to do everything that the no-semicolons parser does.
On the other hand, a semicolon is an explicit statement terminator that the parser doens't have to think about, so it's basically free.
If there is a cost, it is not to the parser or compiler, it is to users reading the code.

Making semicolons optional is not a goal. The goal is to make them all go away, they do indeed not provide any value in the long term.
However, if we keep them optional, existing code will stay valid, and since it doesn't really cost anything, we might as well do so until all code has been migrated off semicolons.

However, when we implement language versioning it is possible to make a breaking syntax change between language versions, so it is possible to have Dart 2.8 with semicolons and Dart 2.9 completely without semicolons without having to worry about backwards compatibility. You'd have to migrate all your code to be able to run it as Dart 2.9, but that migration should be "trivial": parse all the code into a syntax tree using the 2.8 parser, then emit that syntax tree using the 2.9 Dart formatter.

Nobody wants to insert semicolons. What we want is to break statements. A semicolon is an explicit statement break, so that's easy. Without semicolons, the parser has to divine where to break the tokens into separate statements using other rules (like "only at newlines", "not if followed by X", "not if preceded by Y", "unless it's an odd line on a Thursday"). This is doable, but we also want the set of rules to be predictable, which most likely means simple, memorable and few, so users won't make mistakes all the time, and we want the syntax to allow most of the code that is already written if we just remove the existing semicolons. We have not found a set of rules satisfying this—the rules are either too complex and irregular or too simplistic to allow the code that people are already used to writing. The former means that we can't really expect code authors to get things right, which is a bad user experience. The latter means that we would require everybody to start writing code significantly differently from what they do now, and when they don't, they get things wrong, which is again a bad user experience.
If there is a sweet spot, we have not managed to find it yet. It is quite possible that there is none for the current Dart syntax.

(This is also why @munificent keeps saying that listing some cases that seem simple is not an argument for anything, we need the full set of rules for handling the entire language syntax so we can check how they interact with the body of existing code, which could include all code on Pub and all Dart code on Github, in order to be able to properly consider the complexity/consistency trade-offs and see which edge cases of existing code would break.)

@cosinus84
Copy link

cosinus84 commented Sep 18, 2019

Maybe by adding some flag in pubspec.yaml, the packages that don't have it should be used with semicolons (the compiler, etc, will know how to handle them) as long as environment sdk ('>=2.0.0-dev <3.0.0') allows it. For the new/updated packages you will go without semicolons/migrate old project. About removing semicolons I am very sure that there are places where they can easily be removed and some places where needs more thinking (there was a time, some years ago, when this breaking changes were more easy to be done. Now with all the houses along the road it's getting harder or impossible to make the road a highway)

@munificent
Copy link
Member

Maybe by adding some flag in pubspec.yaml

That's basically what the new "language versioning" stuff does. It lets us use the minimum version in the pubspec's SDK constraint to infer what version of Dart your package is operating at. This is, for example, how users will opt into the non-nullable type changes, which are breaking.

We've designed "language versioning" as its own feature so that we can also use it for other future breaking changes. Semicolons are definitely another place where we could consider using this feature, because it would enable us to make other technically breaking changes to the grammar in order to simplify the newline breaking rules.

@SerggioC
Copy link

Make them optional. Thank you.

@curiouscod3
Copy link

Personally, I really don't like using Semicolons;;;; it is not necessary these days.. See Python, Go, it is more readable. and nowadays compilers can recognize without semicolons. you don't have to put semicolons even in Javascript/Typescript.

@RastislavMirek
Copy link

RastislavMirek commented Nov 12, 2019

Great idea, add my vote. I spent years working in languages that contain semicolons. However, after few months with Swift I could see they nothing but extra keystroke (when writting) and visual spam (when reading)... I even persuaded my team to stop writing them in JS/TS.

Please add "optional parenthesis in conditionals, cycles and similar" to discussion as well ("optional" just for backward compatibility). Similarly to semicolons they are just boilerplate both when writing and reading.

@Node0
Copy link

Node0 commented Dec 26, 2019

My apologies for such a long comment
(1000-ish words, 5 mins of reading, feel free to skip to end.)

Everything I'm about to write is my opinion, as shaped by my experiences in production.
If what you read resonates with your experience, then right on!
Else if your code/deploy/troubleshoot lifecycle works well for you, I'm happy for you.

Also, I love Python, I use it all the time so my opinion has nothing to do with
favoring one language over another for the sake of pure visual appeal,
my opinion comes from a pragmatic systems-oriented experience.

Having said that this how I see the whole semicolon/braces/C family
characteristics story with regards to Dart...

Dart isn't Python, it isn't sound to attempt altering core design semantics of a
language so far into its deployed life. Dart was invented in 2011 that's 8 years ago,
one of its chief goals was to be a familiar language to developers coming from
C family languages.

"C family", means parentheses, block braces, and semicolons.

The question isn't whether Python is 'correct' or not, the question is whether
or not it is sound judgment to attempt to alter (starting with semicolons and
then what braces next?) core semantics of a language 8 years after said
language has not only been introduced but gone through numerous evolutionary
optimizations made the jump to a fully typed language and even begun to
successfully re-invent itself as an innovative mobile development language.

The consideration of arrow functions as a parallel case vis a vis semicolon
removal is not relevant here. The comparison is not relevant namely because
arrow functions were a subsequent non-destructive addition for the language.
There was not an extant characteristic that arrow functions sought to replace.
They were an addition which introduced no collisions with extant syntax or
semantics
which had no consequences for libraries and projects written before
arrow functions were introduced. This is not the case with semicolons or any of
the core characteristics of a C family language.

One does not perform an in-situ engine overhaul/redesign, of a reliably designed
ocean liner mid-cruise because the engine case bolt pattern is 'clunkily' or
inconveniently obstructed by the transmission assembly. That isn't done ever.
Dart is that ocean liner, it is predictable, it is reliable, and even better it
is unambiguous vis a vis JS.

Supposing the core team decided to remove semicolons...

Even with a vastly expanded support and tooling team to assist the core
team, there's still the bandwidth limit (management, collaboration cycles)
placed on the core team, to say nothing of the multi-year rollout such a change
would entail (and this is supposing a successful seamless semicolon removal
capability which allows the existing libraries of code and projects to be run
without alterations until their respective authors get around to updating those
repositories).

Dart is in the middle of re-inventing itself and repositioning itself for
dominance on mobile and backend/desktop, these are tricky waters to navigate
successfully, there are many pitfalls to avoid. Deciding to spend a huge amount
of effort to carefully remove (and then mandate non-use of) semicolons (Re:
in-situ engine overhaul/redesign), and that is effort the core team would then
not be spending gaining a competitive edge in the mobile and desktop spaces. To
say nothing of all the extant libraries, packages, and projects already using
the previous version.

All of that effort spent, to successfully remove semicolons...
Ok, what is the return on investment on that effort spend?
A marginal increase in familiarity/likeability from non-C family language developers.
(Let's be honest, almost exactly zero Python developers are going to
drop Flask and Django and come running to Flutter and Dart because of
semicolon removal. Like, that's not a thing, even braces won't do the trick.)

By comparison...

The recent dart2native capability is a huge win and (goodbye dependencies in
production! Hello standalone binaries!!!) is an example of the core team adding
capabilities that make dart much more competitive, extending its usefulness and
hence reach. Even if this doesn't win Python devs, you might see some interest
cropping up from that camp simply due to the pragmatic nature of standalone
binary artifacts (even though Python can do that too).

Flutter on desktop as a serious competitor to electron, now that would be something
new and compelling under the sun. Now Dart would be a credible threat.

Look I like python, I write python, I also compile my python using pyinstaller.
I don't look at my Dart code and think "It would be so nice if
I didn't have to see those semicolons, block by whitespace, and ditch the
braces.".

Instead, I think: "There's Python over there, and there's Dart over here." There isn't some
painful context switch, each one is suited to different types of problem-solving.

Regarding the visual 'noise' of semicolons and braces...

Sure Python is easy to read, but to be honest, JS isn't that hard to read, and
neither is Dart. What bugs me about JS isn't the visual appeal of its syntax,
it's the ambiguous behavior necessitating a bunch of linter tooling and austere
discipline just to make the language predictable. JS has so scarred the thinking
of a generation of web developers, that it's become par for the course to apply
"JS discipline" to any and every programming language. Namely, lint the code
down to the millimeter and then reformat to the point of refactoring it. Why?
Because ambiguity in JS, so now all languages are guilty of "wrong look", and
"wrong semantics" even if they're not. Dart is actually easier to read than JS
and Dart is even easier to reason about than JS.

It's not sensible to paint all programming languages with the same "JS treatment",
just because JS has a hundred rough edges doesn't mean all languages are
minefields now.

I'm going to prefer keeping semicolons (not as optional) and
adding/upgrading the tooling, IntelliSense, etc Automatic detection
of probable statement terminations are alerted to the user.

About semicolons...

After a while, your brain tunes them out and they cease to be so-called
'noise' and simply become an automatic part of the landscape. To be honest, if
one has worked in BASH, Perl, or PHP, C, or C++ (systems side) then this is a
non-issue. Forget Java, we're not even going to invoke Java's developer UX,
and simply stick to the rest of the C family languages.

There is a panoply of languages for people who dislike the C family semantics
and syntax characteristics, both on mobile, on the backend, and on desktop and
each one of those languages adheres to meaningful whitespace, lack of braces,
and some even omit parens with much more devotion to their respective causes,
than a "Jerry Rigged Dart" could.

So I'm all for better code editor tooling intelligence, and dartfmt options,
etc, however, I'm going to be on the side of keeping Dart predictable (from a C
family language perspective) and pursuing competitiveness elsewhere in the
capability landscape of the language.

If you're using the newer ML based editor enhancements (tab nine), then chances
are you're rarely even typing a semicolon anymore.

@cachapa
Copy link

cachapa commented Dec 26, 2019

After a while, your brain tunes them out and they cease to be so-called
'noise' and simply become an automatic part of the landscape.

But that's the very definition of noise. Just because your brain learns to ignore it, doesn't mean it isn't there, just like the background hiss in analog music tapes - you don't really notice it until it's gone.

If semicolons can be made superfluous (which according to this issue is a big "if"), then they become noise and should be removed.

@liudonghua123
Copy link

I think we can make semicolons optional in most clear situations, and keep the semicolons in some rare ambiguous situations. Code without some redundancy semicolons or parentheses will make code clean and more readable and less typing. We can reference some ES 6+ design ideas to make dart writing more efficient and intuitive.

@liudonghua123
Copy link

Here is what eslint try to do with semicolon.

微信图片_20200307215930

Here is its implementation.

@comm1x
Copy link

comm1x commented Mar 17, 2020

Modern languages, like Swift Kotlin has optional semicolon, and it is great.
Don't compare Dart with ugly poor JS, compare it with modern strong powerful languages like Kotlin or Swift.

@Kantulaev
Copy link

I just wanna ask. Can we get optional semicolon in 2020 / 2021 ?

@RastislavMirek
Copy link

RastislavMirek commented Apr 8, 2020

Just my 2 cents, but coming from a JS / Android background, I'd love either "Semicolons - YES" or "Semicolons - NO".

I do not think OPTIONAL semicolons are healthy for a development community for two reasons:

  1. It will lead to needless bikeshedding. Just witness / read up on the endless debate in the JS community over whether or not to use them. So many hours wasted over something purely stylistic. These debates do not help us solve actual problems.
  2. Additionally, it will make reading code harder for beginners, because it will introduce a stylistic distinction that might not be as easily understood by newcomers.

To keep an open mind, I'd love to hear more about the reasoning in support of optional semicolons. Do folks feel it will help adoption? Is it a stepping-stone toward a Dart v3 w/o semicolons?

Languages like Swift & Kotlin with "Semicolons - NO" have in fact optional semicolons. If you want semicolon at the end of each line, you can write it. Compiler will let you. However, no one does it. Neither 1. nor 2. of your points are observed for these languages.

Semicolons should be optional but there should be language wide guideline to not to write it. In case of Dart it will render legacy code with semicolons compilable. For new code, semicolons will considered be obsolete.

@tedhenry100
Copy link

Languages like Swift & Kotlin with "Semicolons - NO" have in fact optional semicolons. If you want semicolon at the end of each line, you can write it. Compiler will let you. However, no one does it.

Completely untrue. I write a semicolon at the end of every line of Swift and Kotlin. I'm not the only person.

@RastislavMirek
Copy link

RastislavMirek commented Apr 8, 2020

Languages like Swift & Kotlin with "Semicolons - NO" have in fact optional semicolons. If you want semicolon at the end of each line, you can write it. Compiler will let you. However, no one does it.

Completely untrue. I write a semicolon at the end of every line of Swift and Kotlin. I'm not the only person.

As always, exceptions, outliers and "I will do it my way people" exists. That's the point of optionality, to allow for some freedom, right? Still, every style guide for Swift I have ever come across (corporate, open source or otherwise) tells you not to use them (including the one from Google). That effectively switches them off for wast majority of code and it is unlikely that beginners will come across such non-standard code. I teach Swift at a university and I've not seen semicolons being used at lectures / tutorials or similar.

@mit-mit
Copy link
Member

mit-mit commented Jun 12, 2020

Closing the present issue; for future discussion please use the main language issue for this: dart-lang/language#72

As for current status, please see dart-lang/language#72 (comment)

@mit-mit mit-mit closed this as completed Jun 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). language-discussion
Projects
None yet
Development

No branches or pull requests