There are some caveats. This, for example, would not work as expected:
foo()
[1,2,3].forEach(bar)
Automatic semicolon insertion wouldn't work here, because the bracket could be a continuation of the last line. The same goes for parentheses at the beginning of a line.
The informal and single easy rule is to prefix lines that begin with punctuation with a semi. In practice only [ and ( crop up, almost nobody begins lines with a prefix increment or decrement. If you use += 1 and -= 1 instead you sidestep that case.
Yes, you could just add a semicolon in front of lines that start with punctuation (tiny percentage of all lines) or you could just stick them at the end of every single line...
The Reply link doesn't show up for a minute or two. I guess it's supposed to force you to think instead of firing off a hasty response. Kind of pointless for one liners but hey...
But isn't that part of learning any language? There are plenty of weird edge cases in other languages but we get used to them. Basically this boils down to:
"When you have a single statement, that stretches out over more than one line, but those lines are legal statements on their own, then it won't work like you want it to"
I would guess that the number of statements that stretch out over many lines are a very small part of the overall number of statements for most code.
But it just seems like most developers think that javascript might insert semicolons all over the place. Which it won't, the rules are clear once you learn them.
1. Prefix lines that start with punctuation, specifically [(-+/ with a ;. Then omit them everywhere else. Lines that start with punctuation are a tiny subset of all lines generally.
2. Postfix every line with a ;, "just in case"
I can't see how nr. 1 is harder. And in case 2 you don't actually put ; at the end of every line, you don't put them after {} blocks for example, so it's not like it's somehow easier to remember.
"Because we're used to doing it that way" is a reason I guess, but not a great one in my opinion.
And where would JavaScript not handle them in a way people don't expect them to be handled?
Comparing Python's handling of semicolons with JavaScript's ASI, you get the following:
-- End of statements
Python and JavaScript: Ends with either a new line or a semicolon.
-- Line joining
Python: whitespace strict, so lines must be either explicitly joined through the `\' escape character, or put inside a parenthesized expression, which ignores whitespace.
JavaScript: non-whitespace strict, so lines don't need to be explicitly joined. Statements may be continued by starting the following line with a continuation token (one of: `[ ( + - /')
-- Exceptions
Python: Parenthesized expressions use a different parser state (ie.: whitespace strict vs non-whitespace strict)
JavaScript: restricted production grammar usually have optional expressions following them, and since they are a valid statement on their own, the statement will be ended with a new line. So, the related information must start in the same line.
Restricted productions are: return, break and continue; Post-fix and prefix operators are included as restricted productions for readability's sake.
I fail to see how that's difficult to remember, or how that's insanely more complex than Python's rules...
I really don't see any problem with the way JavaScript handles it. "Unless the following line can be part of the preceding statement, end the current statement" is a pretty natural thing to me. But well, I guess that's a matter of taste, and you can't really discuss that...
That's not a problem with the line joining stuff. Both `return' and `{ foo: bar }' are ENTIRE VALID statements in their own right.
returnStmt ::= "return" [ expression ] (";" or EOL)
Note that expression is optional, so it's the choice of `return' by itself being a valid statement on its own that "causes problems".
Plus, this is not really a problem that can be solved by simply putting semicolons everywhere. You can't change the parser rules by including or not semicolons.
Also, same thing with break/continue:
breakStmt ::= "break" [ label ] (";" or EOL)
continueStmt ::= "continue" [ label ] (";" or EOL)
`return` may be a valid statement but an object literal is not.
A standalone object literal would likely be interpreted as a block and would throw a syntax error unless it were a simple identifier and a statement `{ foo: <statement> }`, in which case it would not interpret it as an object but exactly what it is, a label and a statement.
This is why JSON parsers which use eval must first wrap the object literal with parens, to make it an expression rather than a statement.
Never said it was an object literal eh. Object literals can only occur inside expressions, that's pretty well defined in the JavaScript AST too, which is described to the utmost detail in the ECMAScript specs.
The thing is:
- `return` alone is a valid statement in its own.
- The parser just need to use a simple lookahead to decide whether the next line is part of the previous statement.
- The parser DON'T change the meaning of your programs.
All that's beside that is a matter of taste. Whether use semicolons or not is up to what sits better with each person. I'm just arguing against the silly and incorrect "technical" arguments against it.
But using semicolons doesn't eliminate those edge cases. Those are just places where auto-semicolon-insert fails to standup to what humans perceive to be the "right" behavior. Semicolons or no, if you put a newline character between return and the retval, you will get the "wrong" behavior.
The examples being put forth in defense of requiring semicolons are really weak.
// 1.
MyClass.prototype.myMethod = function() {
return 42;
} // No semicolon here.
(function() {
// Some initialization code wrapped in a function to create a scope for locals.
})();
There are at least two potential solutions here: 1) put a semicolon after every function declaration, and 2) put a semicolon before every self-executing function. Both work fine. Either way, you have to remember to put a semicolon somewhere, right? No difference in cognitive load. And if you say that #1 is easier to remember because it's more C-like, you've just blown your cover. You don't actually write C at your day job, do you? Because otherwise you'd realize that C does not require semicolons after functions.
[normalVersion, ffVersion][isIE]();
Same thing. Just put a semicolon before lines that start with arrays like this. Also this code is crap.
-1 == resultOfOperation() || die();
OK hold up, who really writes this stuff? Is this what code looks like at Google? Forget semicolons for a second and let's work on basic code readability. Explain the line aloud. "If resultOfOperation returns negative one, then die." Now write it.
if (resultOfOperation() == -1) die();
Sweet, now people can read our code without juggling operator precedence rules in their head. Minor side effect: the semicolon issue goes away.
return
{ foo: bar }
Really? Why oh why would you write such a thing and expect it to return the object?
When compressing javascript down, missing a semi-colon can cause broken js, especially in older IE browsers. Trailing commas on js object literals would also freeze an entire page in IE. When that happened it would often take several days in jslint trying to work out where the broken js was from.
my biggest concerns - why people want to _not_ use semicolons? Does it improve load speed may be? or make code more readable or help with something else?
You point is doubly valid when you consider that the code might be run through Closure or Uglify, and all the truly extraneous semicolons will be removed. At that point, load speed is maximized, and the code is unreadable, semicolons or otherwise.
Since JS source "feels" more C-like than Python-like to me, I think the semicolons are a good idea.
Readability. Python, Ruby, and CoffeeScript are more readable for their parsimonious approach to punctuation, aren't they? We like those languages, right?
Also, JS was not designed from start as semicolon-less language. If you prefer semicolon-less JS - use Coffee Script. Otherwise it is very hard to debug such code for someone who do not expect semicolon-less JS code.
Well, I think it's more readable without semicolons. Less linenoise. And after reading about exactly how it works I'd rather omit them where I can. The cases where it behaves differently than expected are almost all cases where I think "I would never do that anyway"
I don't think that's comparable. Maybe it would be if every new English sentence started on a new line ;)
The capital letter in English is a strong visual indicator that a new sentence is starting. In code I think the line break does that more than well enough, no need for the ;
If memory serves, IBM's PL1 used to insert missing punctuation that it (the compiler) felt was missing. This wasn't particularly well thought out and often caused problems that were very difficult to debug. I used to think of it as 'doing me a favor that I hadn't asked for' and grew to hate both the feature and the language (the language for other reasons). In the years since then I've tried to be consistent in avoiding any such feature. I find it much easier to go ahead and use what ever the language needs. If I use semi-colons, then I don't have to guess there after...
In several years of PL/I programming, the compiler correctly inserted a semi-colon exactly once and then aborted the compile. I remember because it was such a surprise.
Haven't seen mentioned yet that .html files and legacy tools have an extremely lax historical attitude towards whitespace. People of a certain age came to the web understanding that a space is the same as a tab is the same as a line feed, as far as browsers are concerned.
The (increasingly common) practice on minifying is just one offspring of that history, which is, to the main point, not shared with Python.
In general, DWIM (Do What I Mean) is evil. We're better off being forced to say exactly what we mean than having the machine try to figure it out for us. This lesson has been learned repeatedly over the years by programming language designers -- though clearly, alas, not by everyone.
This is probably furthest down on my list of worries when writing JS... Sometimes I use semicolons, sometimes I don't (I try to be consistent in the same file), and when I'm in somebody else's house I follow their style. The examples given for why I should always use semicolons (e.g. the return + value on different line) are things that just don't come up for me and usually look ugly enough I'd avoid them anyway. (Also they're fairly simple to discover if you're actually testing your code.) The last time I did a return and value on the next line was in Java...
You should always endeavour to make your code easy to read. Since most people aren't aware semi colons are optional, omitting them can cause unexpected behaviour in certain cases, and having them there does no harm, it's surely best to stick to the standards (i.e. using semi colons). The only time to debate whether to omit them is when there's a good reason to leave them out. Also, I suspect (untested theory) that it puts more strain on the parser, though makes negligible difference to the download speed, so will be a hit on performance.
Reason #1: Every time it comes up everyone who uses semicolons but doesn't really know why pipes up with their misguided and misinformed views on why dragons will eat your heart if you leave them out. Just look at the comments here.
return i++ is not ambigous. It will return the current value of i, e.g. if i was 2 it will return 2, not 3. But that's just how the post increment operator works (in every language that I know of), that has nothing to do with semicolon insertion.
"return i++" is not ambiguous, on that you are correct--but it is terrible practice because it lends itself to being misconstrued.
Writing clear code is superior to writing "cute" code, and "return i++" is a case of the latter. In any case where the increment actually matters you are directly affecting a shared state and such changes should be made contextually obvious to the state of the object--one's neck would need to be very, very beard to think that this is immediately obvious and apparent in a contextually valid way.
Similarly, for many programmers, myself included, a semicolon is read as a period is in English--the end of the statement. (You keep saying that "but people don't get annoyed at Python when it does it," and guess what? I certainly get annoyed at it--Python consistently frustrates me because I find it considerably less readable.) Omitting semicolons is less immediately clear than including them and, again, can be misconstrued. Only it can be misconstrued by the program interpreter, too. (Oops.)
I prefer to avoid Python entirely, but there are cases where I have to fiddle with preexisting code or the nature of the problem makes more sense to use it, i.e. a library already exists that doesn't elsewhere. In those cases, I write idiomatic Python, without semicolons, because That's The Way You Write Python.
Consistency is important, and the Python community has essentially said "don't use semicolons." The JavaScript community has essentially said "use semicolons aggressively". I write code according to those idioms so other people are able to more easily use it.
Yes it is. My point is that when those guys created their respective languages, they omitted semicolons. One would surmise that they thought it made things better.
Also apparently Brendan Eich, since he included the feature in the language, continues to speak of it without shame and has used it on his blog as an example of what he'd like to see code look like (with the comment that "JSLint can suck it").
Source: http://blog.izs.me/post/2353458699/an-open-letter-to-javascr...