"use real strict" mode?

I'm proposing a new feature where one could use "use real strict" instead of "use strict". It does everything that the "use strict" does plus disables Automatic Semicolon Insertion (ASI) logic. If the code has invalid grammar, always raise syntax error instead of trying to fix the code automatically by adding semicolon.

The real strict mode could maybe disable support for "var" and other old features, too, if it's not too hard to implement in practice.

The ASI is the only feature that I consider bad enough to be possible to turn off, but feel free to suggest other non-wanted features in current "use strict" mode.

Even if the prevailing attitude in the committee wasn't "no new modes, ever", I fail to see how this is worth it.

You can already avoid ASI hazards by using a linter (preferably to enforce the presence of semicolons, but either way). Engines already have to parse files multiple times because of hoisting, so I don't think there'd be any performance gain by disabling ASI either.

There's nothing wrong with "var", and no reason to disable support for it; a linter can do that too (and most do).

1 Like

See also this conversation: Proposal: disable automatic semicolon insertion (looking for champion)

1 Like

I think all the arguments that were used to introduce "use strict" could be used for "use real strict", too. The "use strict" doesn't do anything that a good linter couldn't do either.

However, if there has been a decision to not introduce new modes in future, there's no sane way to disable ASI.

The linked discussion makes it appear like semicolons were optional in JS. In fact, semicolons are required but the language contains automatic code assist feature that detects invalid syntax and tries to fix the code by adding a semicolon. I was just hoping that such automatic code modification system could be disabled. Unfortunately, the original strict mode didn't disable this feature.

Note that the spec says:

"When, as the program is parsed from left to right, a token (called the offending token ) is encountered that is not allowed by any production of the grammar, then a semicolon is automatically inserted before the offending token [...]"
Source: ECMAScript Language Specification - ECMA-262 Edition 5.1

So obviously the semicolon is not optional, but a missing semicolon will be automatically added if syntax is invalid ("not allowed") otherwise.

Would a new mode be a non-option even if it allowed better real world performance? For example, if a new mode disabled both hoisting and ASI, it would allow faster parsing.

Well, what do you mean by "required". Many people (myself included) choose to code without semicolons because ASI exists. It's been know for some time now that this can be done safetly. So, it really doesn't matter how ASI works, even if it is a simple code-assest tool that blindly adds semicolons every time a parse error is found, the fact that it's there is what makes them optional, and the fact that it follows a deterministic algorithm is what lets people safety code around its flaws. Perhaps, after this parse step is run, they're internally required, but that's more of an implementation detail.

This isn't to say that I like ASI. I would much rather have a language that never had ASI in the first place, where we'd all be required to use semicolons. If I'm honest with myself, it would be better if I used semicolons in my own code as well, but, as I don't like semicolons much, and they're not required, and there's known patterns to safetly code without them, I choose not to use them.

Anyways, I'm just arguing semantics now. Let me bring up something with more substance.

Another thing that "use strict" had going for it, is that it was fixing a whole lot of issues at once. Perhaps, if we could time travel, we could ask them to also drop ASI support when use-strict was enabled, but it's a little late for that. Other things you brought up, like "var" is just an old way of doing things, it isn't a foot-gun or bad if you use it, it just means you're not using the best tools available to you. And, I find it difficult to make an argument for adding an entire directive centered around fixing one thing (ASI), as bad as it is.

The "use strict" doesn't do anything that a good linter couldn't do either.

That's incorrect; among other things, strict mode changes the default receiver from the global to undefined - a linter can't do that.

2 Likes

Honestly I use that feature a lot; like @theScottyJam said, it's a matter of understanding the pitfalls and working around the flaws; I guess that's the general word of advice for programming in JavaScript anyways.

"People are afraid of things that they don't understand" - ASI is one of those things I guess.
I'm more bugged by weird coercion rules of the language more than anything else. I just wanted to say that a considerable amount of people like me prefer ASI.

Instead of going "against" ASI, why not just enforce consistency of ASI rules instead? The fact that JS thinks these 2 are independent tokens:

return
    4

But these are a single expression:

const x = [0, 1, 2]
[0]

Is very unexpected and weird. Until you realize return is a statement, and [] is a expression. Expressions have a tendency to "touch" each other when they are nearby, while statements have a strict start/end-points. This is not always the case:

a = 0
b = 1

Are both expressions, but they never "touch", until you put them on the same line. I think this is one of the reasons why ASI seems inconsistent

1 Like
return
    4

This is specifically prohibited by the grammar because of [no LineTerminator here]. Otherwise it's perfectly fine to "stick".