excluding features from sloppy mode

# Brendan Eich (12 years ago)

David Herman wrote:

On Dec 26, 2012, at 3:35 PM, Mark S. Miller<erights at google.com> wrote:

I think you did coin "1JS". What do you mean by it? Does it bear on the present issue or not?

I coined the "just one JavaScript" here:

 https://mail.mozilla.org/pipermail/es-discuss/2011-December/019112.html

And it got shortened to 1JS not long after (maybe in the same thread?). The key point was no (new) opt-in for ES6. If you read the message (see the "Modules as the opt-in for new semantics" section), you'll see that I actually proposed that anything that can't be made to work in legacy code can be left out of sloppy mode.

Not arguing in reply, rather taking this opportunity to expound/recollect a bit, bear with me!

The lingering, not-quite-resolved issue I see Mark raising depends on the exact definition of "can be left out of sloppy mode" or (should that be reworded?) "can be included in sloppy mode but only with some incompatibility or contortion [but not binding-dependent parsing]".

Long before 1JS, in prototyping ES4 features in SpiderMonkey "JS1.7" and up (which ended up in Rhino as well), and inspired by Opera's array destructuring, we started adding new features without requiring opt-in version selection. The new syntax was enough. This covered destructuring, and it turned off sloppy-mode craziness that was hard to implement or teach (e.g., destructuring parameters made duplicate formal parameters an error in JS1.7+, prefiguring strict mode).

We ran into problems with 'let' and 'yield' used as identifiers, and lacking function* syntax for generators, we did require opt-in by version= for those two but nothing else.

With 1JS as you proposed it (and if my memory serves), 'module' was enough to opt into new syntax (and it also implied "use strict"), but there was room for other new syntax outside of module (and outside of "use strict") to be its own opt-in.

Since then I think TC39 has moved along toward enabling opt-in by new syntax where it's clean. New function head syntax (rest, default, destructuring parameters; function* for generators, which reserves yield in the body), at least.

We knew 'let' could be a problem. Also we knew function-in-block was a breaking change. As you noted, and Brandon nicely separated in his reply as well, we can certainly require "use strict" to have function-in-block semantics. We may be left with no other choice.

Just to recap the last TC39 meeting, we agreed to try reserving 'let' in sloppy mode. Mark wasn't happy about that, not so much because of incompatibility due to let[x] = y; changing meaning, more -- this is my interpretation, Mark should correct me -- because he wanted to promote strict mode, not elaborate sloppy mode ("don't polish a turd") , and keep each mode simpler by most measures.

I do not think the problems we anticipated with function-in-block and 'let' mean we retreat to requiring "use strict" for all new syntax outside of implciitly-strict modules. This is my punch-line: function-head new syntax in sloppy mode, including stricter error checking (e.g. for duplicate formals), should stand. It is better for the users, and probably even for the spec, to make such new syntax its own opt-in.

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

all seem to work in 1JS via the "new syntax is its own opt-in" rule, including any stricter/saner semantic checking.

I left out 'let' and function-in-block. Let's set those aside for a moment.

Anyone disagree that the bulleted syntactic extensions listed above should be their own opt-in, and think instead that some or others or all should appear only to strict code? (Mark, here's your chance! ;-)

# Mark S. Miller (12 years ago)

On Wed, Dec 26, 2012 at 5:54 PM, Brendan Eich <brendan at mozilla.com> wrote:

David Herman wrote:

On Dec 26, 2012, at 3:35 PM, Mark S. Miller<erights at google.com> wrote:

I think you did coin "1JS". What do you mean by it? Does it bear on the present issue or not?

I coined the "just one JavaScript" here:

esdiscuss/2011-December/019112

And it got shortened to 1JS not long after (maybe in the same thread?). The key point was no (new) opt-in for ES6. If you read the message (see the "Modules as the opt-in for new semantics" section), you'll see that I actually proposed that anything that can't be made to work in legacy code can be left out of sloppy mode.

Not arguing in reply, rather taking this opportunity to expound/recollect a bit, bear with me!

The lingering, not-quite-resolved issue I see Mark raising depends on the exact definition of "can be left out of sloppy mode" or (should that be reworded?) "can be included in sloppy mode but only with some incompatibility or contortion [but not binding-dependent parsing]".

Long before 1JS, in prototyping ES4 features in SpiderMonkey "JS1.7" and up (which ended up in Rhino as well), and inspired by Opera's array destructuring, we started adding new features without requiring opt-in version selection. The new syntax was enough. This covered destructuring, and it turned off sloppy-mode craziness that was hard to implement or teach (e.g., destructuring parameters made duplicate formal parameters an error in JS1.7+, prefiguring strict mode).

We ran into problems with 'let' and 'yield' used as identifiers, and lacking function* syntax for generators, we did require opt-in by version= for those two but nothing else.

With 1JS as you proposed it (and if my memory serves), 'module' was enough to opt into new syntax (and it also implied "use strict"), but there was room for other new syntax outside of module (and outside of "use strict") to be its own opt-in.

Since then I think TC39 has moved along toward enabling opt-in by new syntax where it's clean. New function head syntax (rest, default, destructuring parameters; function* for generators, which reserves yield in the body), at least.

We knew 'let' could be a problem. Also we knew function-in-block was a breaking change. As you noted, and Brandon nicely separated in his reply as well, we can certainly require "use strict" to have function-in-block semantics. We may be left with no other choice.

Just to recap the last TC39 meeting, we agreed to try reserving 'let' in sloppy mode. Mark wasn't happy about that, not so much because of incompatibility due to let[x] = y; changing meaning, more -- this is my interpretation, Mark should correct me -- because he wanted to promote strict mode, not elaborate sloppy mode ("don't polish a turd") , and keep each mode simpler by most measures.

You got it. I don't want to see the overall language become more complex just so we can provide new features to sloppy mode.

I think the core of our disagreement is this:

Until ES3 browsers become insignificant, there is the additional testing burden you mention. This is a transitional issue, but I agree it is a significant one. But it will be years before ES6 rolls out in browsers. Old browser versions fade out much faster than they used to (due mainly to more aggressive auto update). So I do not expect significant practical overlap between ES6 browsers and ES3 browsers.

Superstition aside, and once pre-ES5 browsers are not significant, the only purpose of sloppy mode is for old code that must be kept running without active maintenance. For any code being actively maintained, it should move into strict mode. Sloppy mode will become a relic only for code no one touches.

I do not think the problems we anticipated with function-in-block and 'let' mean we retreat to requiring "use strict" for all new syntax outside of implciitly-strict modules. This is my punch-line: function-head new syntax in sloppy mode, including stricter error checking (e.g. for duplicate formals), should stand. It is better for the users, and probably even for the spec, to make such new syntax its own opt-in.

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

all seem to work in 1JS via the "new syntax is its own opt-in" rule, including any stricter/saner semantic checking.

I left out 'let' and function-in-block. Let's set those aside for a moment.

Anyone disagree that the bulleted syntactic extensions listed above should be their own opt-in, and think instead that some or others or all should appear only to strict code? (Mark, here's your chance! ;-)

I would apply one simple test to all of these: Does it make the overall language simpler, and strict mode no more complex, to make these available in sloppy mode as well? Most of these pass this test. Once we started talking about micro-modes for new function syntaxes, it became clear that these do not. So for these, if they cannot be provided to sloppy mode without micro-modes, they shouldn't be provided to sloppy mode at all.

# Axel Rauschmayer (12 years ago)

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

all seem to work in 1JS via the "new syntax is its own opt-in" rule, including any stricter/saner semantic checking.

I left out 'let' and function-in-block. Let's set those aside for a moment.

Anyone disagree that the bulleted syntactic extensions listed above should be their own opt-in, and think instead that some or others or all should appear only to strict code? (Mark, here's your chance! ;-)

Am I getting the following grouping right? I’d argue that all members of the second category usually have small bodies; having ES6 syntax only there might make things too fragmented.

(1) opt-in for bodies:

  • class
  • default parameters
  • rest parameters
  • destructuring (parameters?)
  • generators (function*, yield in function* body)
  • module

(2) opt-in for surrounding scope:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • const
  • comprehensions
  • generator expressions
# Brendan Eich (12 years ago)

Axel Rauschmayer wrote:

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

all seem to work in 1JS via the "new syntax is its own opt-in" rule, including any stricter/saner semantic checking.

I left out 'let' and function-in-block. Let's set those aside for a moment.

Anyone disagree that the bulleted syntactic extensions listed above should be their own opt-in, and think instead that some or others or all should appear only to strict code? (Mark, here's your chance! ;-)

Am I getting the following grouping right? I’d argue that all members of the second category usually have small bodies; having ES6 syntax only there might make things too fragmented.

(1) opt-in for bodies:

  • class
  • default parameters
  • rest parameters
  • destructuring (parameters?)
  • generators (function*, yield in function* body)
  • module

Right so far.

(2) opt-in for surrounding scope:

  • arrow function syntax (which does not imply "use strict" in body prologue)

No, there's no reason for such opt-in given 1JS's "new syntax is its own opt-in selector". If somewhere else, 3000 lines down, you need a comprehension, use it then. No need for the arrow here to enable the comprehension there, or vice versa. No enabling outside of the syntax-that-enables-itself.

  • const

Already reserved (in some sense, even if equated to var in Opera), no opt-in required. This identifier was reserved in ES1.

  • comprehensions

Same as arrows, no surrounding scope taint and no need for it.

  • generator expressions

Ditto.

# Brendan Eich (12 years ago)

Brendan Eich wrote:

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

I left out for-of loops that go with comprehensions and genexps like peas and carrots -- obviously for (x of o) is illegal in JS today, so there's no forward compatibility and the new for (x of o) body(); loop statement syntax again can be its own opt-in.

# Axel Rauschmayer (12 years ago)
  • const

Already reserved (in some sense, even if equated to var in Opera), no opt-in required. This identifier was reserved in ES1.

But for const <x> = <y>

const is opt-in for <x> and <y>, right? Not sure that that makes much of a difference, though.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Wed, Dec 26, 2012 at 5:54 PM, Brendan Eich<brendan at mozilla.com> wrote:

Just to recap the last TC39 meeting, we agreed to try reserving 'let' in sloppy mode. Mark wasn't happy about that, not so much because of incompatibility due to let[x] = y; changing meaning, more -- this is my interpretation, Mark should correct me -- because he wanted to promote strict mode, not elaborate sloppy mode ("don't polish a turd") , and keep each mode simpler by most measures.

You got it. I don't want to see the overall language become more complex just so we can provide new features to sloppy mode.

I think the core of our disagreement is this:

Until ES3 browsers become insignificant, there is the additional testing burden you mention. This is a transitional issue, but I agree it is a significant one. But it will be years before ES6 rolls out in browsers. Old browser versions fade out much faster than they used to (due mainly to more aggressive auto update). So I do not expect significant practical overlap between ES6 browsers and ES3 browsers.

Yes, I agree and I have hopes we are "over the hump" on ES3 => ES5 (where "use strict"; is meaningful).

Superstition aside, and once pre-ES5 browsers are not significant, the only purpose of sloppy mode is for old code that must be kept running without active maintenance.

That is a teleological statement -- you're talking about purpose, designed intent, goal, "The Good (Life)".

Very philosophical, I dig it ;-). However, in reality as Dave said in a recent message, the Law of Least Effort says people will forget to write "use strict"; and we'll have sloppy mode code till the cows come home.

Wherefore my point about pedagogy. But you can't assume teaching will eliminate sloppy mode on a definite schedule, or even an indefinite but perhaps foreseeable one (~5 years? 10 for sure) wherein pre-ES5 browsers die off (including IE9).

For any code being actively maintained, it should move into strict mode.

Very hortatory, but the kids are alright and they don't all follow a single "should". Between dissenters and LoLE or Law of Murphy ;-), I bet your "should" will become an ineffectual nag over the next few years.

If, one fine day, virtually everyone does as in Perl and starts their programs with "use strict'; (or "module {" with closing "} after), I will raise a toast to you and others who helped teach that practice. It's nowhere near a certainty, and "should" isn't "would" or "will".

Sloppy mode will become a relic only for code no one touches.

Perhaps, but not on a predictable schedule and not (if I'm right) within the next few years, when we want ES6 adoption -- including new syntax.

I do not think the problems we anticipated with function-in-block and 'let' mean we retreat to requiring "use strict" for all new syntax outside of implciitly-strict modules. This is my punch-line: function-head new syntax in sloppy mode, including stricter error checking (e.g. for duplicate formals), should stand. It is better for the users, and probably even for the spec, to make such new syntax its own opt-in.

So, case by case:

  • arrow function syntax (which does not imply "use strict" in body prologue)
  • class
  • const
  • default parameters
  • destructuring
  • rest parameters
  • generators (function*, yield in function* body)
  • comprehensions
  • generator expressions
  • module

all seem to work in 1JS via the "new syntax is its own opt-in" rule, including any stricter/saner semantic checking.

I left out 'let' and function-in-block. Let's set those aside for a moment.

Anyone disagree that the bulleted syntactic extensions listed above should be their own opt-in, and think instead that some or others or all should appear only to strict code? (Mark, here's your chance! ;-)

I would apply one simple test to all of these: Does it make the overall language simpler, and strict mode no more complex, to make these available in sloppy mode as well? Most of these pass this test.

Great, we agree -- provided "most" == "all" in my bulleted list, which left out 'let' and f-i-b.

Once we started talking about micro-modes for new function syntaxes, it became clear that these do not.

There's no "micro-mode", though. There is simply definite, singular semantics for the new syntax, including error throwing.

(I should clarify (Axel misread this and I didn't catch it in replying to him in my previous message) that destructuring, etc. in function heads does not imply "use strict".)

Again, new syntax speaks for itself. There is no simpler approach, because anything else must use a grammar common to strict and sloppy modes, but then throw early errors, or create poison-pill functions that throw when called, or worse.

Thus I contend that the real mode problem to avoid is one that enlarges ES5 strict to include new syntax and semantics.

So for these, if they cannot be provided to sloppy mode without micro-modes, they shouldn't be provided to sloppy mode at all.

I think you're using "micro-modes" as a curse without actually exploring the alternative costs. Destructuring parameters, or default and rest parameters, are easier to spec (implement) if one does not need to write a "am I in non-strict code, including looking ahead to a prologue in the body of the function whose head I'm in the midst of evaluating?" Such new forms are easier to understand if they speak for themselves, too.

There's no mode-splitting, no extra "if" statements in the spec (implementation).

On the other hand, pushing such new forms that can speak for themselves into the strict dialect means one must festoon the semantics with extra checks.

I fear your animus for sloppy mode is overshadowing the costs (or else the "new head syntax implies strict body" confusion is in play).

Finally, to connect to the first point, strict mode has some overhead (LoLE works against it, people forget to type the directive). I know developers who do not use strict mode, but who will rapidly adopt rest and default parameters, destructuring in general, and other new forms. This adoption of ES6 is partly subjective, distributed over time and (head-)space. It should not be yoked to strict mode adoption.

Yoking the two multiplies the likelihood of adoption to get a smaller product. That's why I favor implicit strict mode only for bodies of new head syntaxes, starting with module as Dave proposed.

I'm ok wtih class opting its body into strict mode, although did we decide that one way or the other? I forget.

Arrows we agreed should be strict or not depending on context and (if context is sloppy) whether their (block statement) body has a "use strict"; directive in its prologue.

Generator functions, as with class, I'm ok if 'function*' implies strict body, but this was not agreed to in TC39 meetings, IIRC.

Please let me know if I've misremembered anything.

# Brendan Eich (12 years ago)

Axel Rauschmayer wrote:

  • const

Already reserved (in some sense, even if equated to var in Opera), no opt-in required. This identifier was reserved in ES1.

But for const <x> = <y> const is opt-in for <x> and <y>, right? Not sure that that makes much of a difference, though.

How could it matter? We are not changing runtime semantics (a la ES5 strict mode). Any new syntax in <x> or <y> is its own opt-in.

See my followup to the offshoot thread Mark started, about "excluding features from sloppy mode", for clarification on new head syntax for functions not opting the body into strict mode. (Ditto for 'class' body strictness, IIRC; 'module' does imply strict body, in contrast.)

# Brendan Eich (12 years ago)

Brendan Eich wrote:

Axel Rauschmayer wrote:

  • const

Already reserved (in some sense, even if equated to var in Opera), no opt-in required. This identifier was reserved in ES1.

But for const <x> = <y> const is opt-in for <x> and <y>, right? Not sure that that makes much of a difference, though.

How could it matter? We are not changing runtime semantics (a la ES5 strict mode). Any new syntax in <x> or <y> is its own opt-in.

I just remembered that we did accept one runtime semantic change (which improves the language by having static semantics for where completions can come from): harmony:completion_reform.

But this proposal won't affect <x> and <y> in your example. It is

observable only via eval or equivalent.

# Kevin Smith (12 years ago)

First, maybe the "1JS" term is a bit confusing and should be retired.

I think a few simple rules are in order:

  1. No opt-in required for new syntax, except:
  2. No breaking changes for sloppy mode.
  3. No implicit opt-in to strict mode.

Everyone agrees on rule #1. Rule #2 implies no "let" declarations in sloppy mode, and no breaking block function semantics in sloppy mode. (Are there others?) Rule #3 is probably the most controversial, but I think it's important.

If we have implicit opt-in to strict mode via new syntax:

  • Figuring out what code is sloppy and what code is strict is going to end up the domain of language lawyers. A casual user should not have to know when a particular syntactic feature was added in order to know what are the runtime semantics for that code. All a casual user should have to know is to put "use strict' at the top of the file.

  • Taking advantage of new syntax (perhaps in the head of a function) will trigger completely unrelated semantic changes. This feels messy.

# Brendan Eich (12 years ago)

Kevin Smith wrote:

First, maybe the "1JS" term is a bit confusing and should be retired.

You're not in marketing, are you :-P.

(I wasn't for most of my career but ended up doing it 50-50 with talent scouting/coaching/nagging. Sucks to be me! :-P)

1JS is too short and tweet-sweet to die.

I think a few simple rules are in order:

  1. No opt-in required for new syntax, except:
  2. No breaking changes for sloppy mode.
  3. No implicit opt-in to strict mode.

Everyone agrees on rule #1. Rule #2 implies no "let" declarations in sloppy mode, and no breaking block function semantics in sloppy mode. (Are there others?)

Completion reform, a runtime semantic change. See harmony:completion_reform.

Rule #3 is probably the most controversial, but I think it's important.

Indeed, it goes against Dave's original proposal that module opt into strict mode, which avoids some problems with sloppy mode in modules, e.g. implicitly created globals by assignment to free names.

If we have implicit opt-in to strict mode via new syntax:

  • Figuring out what code is sloppy and what code is strict is going to end up the domain of language lawyers. A casual user should not have to know when a particular syntactic feature was added in order to know what are the runtime semantics for that code. All a casual user should have to know is to put "use strict' at the top of the file.

This is a slippery-slope argument. Contra some controversialists, I do not find such arguments fallacious on their face. Lots of bad things happened by "boiling the frog" (in real life I'm told the frog jumps out in time).

On the other hand, Dave proposed 1JS with only module implicitly opting its bodoy into strict mode. That is a line we can probably hold.

I suggest (I'm not sure, need to think more) that adding class (and perhaps even function*) to the set of "heads" whose bodies are implicitly strict wouldn't slide too far down-slope, but going from 1 to

1 is the big bad change. So let's say that only 'module' implies

strict code in its body.

  • Taking advantage of new syntax (perhaps in the head of a function) will trigger completely unrelated semantic changes. This feels messy.

That's right, and we (TC39, and es-discuss too IIRC) agreed that new function head syntax, whatever it might do in the way of banning duplicate formal parameters, does not imply strict mode for the function's body.

# Kevin Smith (12 years ago)

You're not in marketing, are you :-P.

No - and if I had any marketing sense I'd have a much better day job : )

Indeed, it goes against Dave's original proposal that module opt into

strict mode, which avoids some problems with sloppy mode in modules, e.g. implicitly created globals by assignment to free names.

Does this mean any script loaded as a module?

import something from "x.js";

So "x.js" would be strict mode code, even if it doesn't start with "use strict;"?

# Brendan Eich (12 years ago)

Kevin Smith wrote:

Indeed, it goes against Dave's original proposal that module opt
into strict mode, which avoids some problems with sloppy mode in
modules, e.g. implicitly created globals by assignment to free names.

Does this mean any script loaded as a module?

import something from "x.js";

So "x.js" would be strict mode code, even if it doesn't start with "use strict;"?

I finally did what I have done before, and should have done again: re-read Dave's o.p. on what became known as "1JS":

esdiscuss/2011-December/019112

It does not even contain the word "strict". IIRC (and I asked about this at the last TC39 meeting and got verbal confirmation), the idea of module {...} implying strict mode was latent, or intended. I'm not sure about out of line modules.

At this point, best thing is to summon Dave.

For myself, I'll note that like any good meme or brand, "1JS" has fluctuating meaning. It needs to be specified, for sure. It is somewhat protean but not (yet) full of contradictions or conflicts. This is a good thing (see my marketing joke). As we firm it up, we can afford to lose implicit assumptions (e.g., module implies strict) that make things simpler, as you propose. But we shouldn't throw out the name or the underlying fuzzy concept.

# Kevin Smith (12 years ago)

It does not even contain the word "strict". IIRC (and I asked about this at the last TC39 meeting and got verbal confirmation), the idea of module {...} implying strict mode was latent, or intended. I'm not sure about out of line modules.

At this point, best thing is to summon Dave.

Since any new code will likely be written as a module (even in the near-term, transpiled back to ES5), this would be the ideal scenario. But I'm trying to think through the implications while waiting.

# Brendan Eich (12 years ago)

Kevin Smith wrote:

It does not even contain the word "strict". IIRC (and I asked
about this at the last TC39 meeting and got verbal confirmation),
the idea of module {...} implying strict mode was latent, or
intended. I'm not sure about out of line modules.

At this point, best thing is to summon Dave.

Since any new code will likely be written as a module (even in the near-term, transpiled back to ES5), this would be the ideal scenario.

Which "this" do you mean? modules (in or out of line) implying strict mode can target ES5 strict, no problem.

But I'm trying to think through the implications while waiting.

One more thought from me, then I'll shut up for a bit:

Mark wants no "micro-modes" but really (and I appreciate his candor) wants no sloppy mode extension if possible. I see things differently but I've started coming down on the side of more implicit strictness: module, class, function*, perhaps we should revisit arrows. (Allen has to spec something in the way of poisoned or absent .caller, etc. on arrow function objects.)

IOW, I want more strict extensions too, but implicitly! Again, having to write "use strict"; itself makes for more sloppy code over time, but new syntax can be its own reward for the new semantics.

So I'm not convinced your slippery slope argument should prevail.

# Mark S. Miller (12 years ago)

On Thu, Dec 27, 2012 at 12:24 AM, Brendan Eich <brendan at mozilla.com> wrote:

Kevin Smith wrote:

It does not even contain the word "strict". IIRC (and I asked
about this at the last TC39 meeting and got verbal confirmation),
the idea of module {...} implying strict mode was latent, or
intended. I'm not sure about out of line modules.

At this point, best thing is to summon Dave.

Since any new code will likely be written as a module (even in the near-term, transpiled back to ES5), this would be the ideal scenario.

Which "this" do you mean? modules (in or out of line) implying strict mode can target ES5 strict, no problem.

But I'm trying to think through the implications while waiting.

One more thought from me, then I'll shut up for a bit:

Mark wants no "micro-modes" but really (and I appreciate his candor) wants no sloppy mode extension if possible. I see things differently but I've started coming down on the side of more implicit strictness: module, class, function*, perhaps we should revisit arrows. (Allen has to spec something in the way of poisoned or absent .caller, etc. on arrow function objects.)

IOW, I want more strict extensions too, but implicitly! Again, having to write "use strict"; itself makes for more sloppy code over time, but new syntax can be its own reward for the new semantics.

Geez I find this tempting. But I cannot agree. Code is read more often than it is written, and ease of opting into strict mode isn't worth the price of making it harder to tell which code is in strict mode. I agree with Kevin's point #3. "function*" and arrow functions, being functions, have function bodies. For "function" functions, they opt into strict if they begin with "use strict". It would be confusing to a reader of code for some functions to do this implicitly. It would not be confusing for readers to not have "function*" or arrow functions available in sloppy mode. When reading sloppy code, these new function forms wouldn't appear without a "use strict" pragma, and so wouldn't raise any new strictness questions for readers.

Class is an interesting case though, for three reasons.

  1. Its body is not a function body, and so it would be yet more syntax to enable a class to opt into strict mode explicitly.
  2. It is a large-grain abstraction mechanism, much like modules, and often used as the only module-like mechanism in many existing programming languages. (Yes, JavaScript is a different language. But we called it "class" to leverage some of that prior knowledge.)
  3. It looks as foreign to old ES3 programmers as does module.

So I recommend no implicit opt-in, except for module (of course) and possibly class. If class does not implicitly opt in, we need to extend the class body syntax to accept a "use strict" pragma.

As for what function forms or heads require explicit opt-in, that hangs on the micro-mode issue. If you're right that we would not make things simpler if these were available only in strict mode, then I agree with your conclusion. More later after I review where these micro-modes ended up, especially the scoping issues on default argument expressions. What's the best thing to read to understand the current state of these? How well does the current draft spec reflect the current agreements?

I do think "let" should only be available in strict mode, rather than the syntactic crazy rules we started to invent at the last meeting.

In writing this list, I realize that the specific issue that set me off, f-i-b, is a red herring. Because of ES3 practice, everyone will continue to support f-i-b somehow in sloppy mode. If we can get everyone to adopt the block-lexical semantics for sloppy that they have in strict mode, that's simpler than maintaining the current de facto crazy semantics for these in sloppy mode and having them have block lexical semantics in strict code. So I'm on board with evangelizing the problem web sites to fix their f-i-b code.

# David Bruant (12 years ago)

Le 27/12/2012 06:32, Brendan Eich a écrit :

Mark S. Miller wrote:

Superstition aside, and once pre-ES5 browsers are not significant, the only purpose of sloppy mode is for old code that must be kept running without active maintenance.

That is a teleological statement -- you're talking about purpose, designed intent, goal, "The Good (Life)".

Very philosophical, I dig it ;-). However, in reality as Dave said in a recent message, the Law of Least Effort says people will forget to write "use strict"; and we'll have sloppy mode code till the cows come home.

The Law of Least Effort also brought us compile-to-JS languages. Coffeescript still doesn't compile with "use strict"; by default [1], but it seems open to it when all non-strict browsers will have died and the perf issues are solved. In the future, I expect:

  • more usage of compile-to-JS languages
  • all compile-to-JS languages to compile to strict mode by default

Interestingly, this would turn the result of the Law of Least Effort from "some will forget" to "people won't forget". Of course people will probably always write handwritten JS and some will forget to put "use strict";, but I feel new non-strict code will eventually become a rare exception asymptotically leading to, but never reaching inexistence.

For any code being actively maintained, it should move into strict mode.

Very hortatory, but the kids are alright and they don't all follow a single "should". Between dissenters and LoLE or Law of Murphy ;-), I bet your "should" will become an ineffectual nag over the next few years.

If, one fine day, virtually everyone does as in Perl and starts their programs with "use strict'; (or "module {" with closing "} after), I will raise a toast to you and others who helped teach that practice. It's nowhere near a certainty, and "should" isn't "would" or "will".

I feel this will happen when compile-to-JS compile by default to strict mode. Only years will tell.

Sloppy mode will become a relic only for code no one touches. Perhaps, but not on a predictable schedule and not (if I'm right) within the next few years, when we want ES6 adoption -- including new syntax.

I sadly agree.

Finally, to connect to the first point, strict mode has some overhead (LoLE works against it, people forget to type the directive). I know developers who do not use strict mode, but who will rapidly adopt rest and default parameters, destructuring in general, and other new forms. This adoption of ES6 is partly subjective, distributed over time and (head-)space. It should not be yoked to strict mode adoption. +1

Yoking the two multiplies the likelihood of adoption to get a smaller product. That's why I favor implicit strict mode only for bodies of new head syntaxes, starting with module as Dave proposed.

I'm ok wtih class opting its body into strict mode, although did we decide that one way or the other? I forget.

I don't know, but I'd be in favor of implicit strict in classes. Moving code to module and classes would be the gradual move to strict mode Mark talks about. If people notice perf issues against equivalent not-in-module/class code, they'll report it. Hopefully, that'll be an incentive enough for implementors to make strict mode at least as fast as sloppy mode.

David

[1] jashkenas/coffee-script#2337

# Kevin Smith (12 years ago)

Since any new code will likely be written as a module (even in the

near-term, transpiled back to ES5), this would be the ideal scenario.

Which "this" do you mean? modules (in or out of line) implying strict mode can target ES5 strict, no problem.

"This" meaning all module code (in or out-of-line) is implicitly strict. If that's the case, then implicit rules for anything else essentially becomes moot: module code will dominate by far. Even in the near term, many developers will start writing in ES6 modules, and transpiling back to ES5. If all modules are strict, then the transpiler will insert the required "use strict" directive, and all is good.

To put another spin on it, how often will we see a class that is outside of any module?

# Russell Leggett (12 years ago)

On Dec 27, 2012, at 8:54 AM, Kevin Smith <khs4473 at gmail.com> wrote:

Since any new code will likely be written as a module (even in the near-term, transpiled back to ES5), this would be the ideal scenario.

Which "this" do you mean? modules (in or out of line) implying strict mode can target ES5 strict, no problem.

"This" meaning all module code (in or out-of-line) is implicitly strict. If that's the case, then implicit rules for anything else essentially becomes moot: module code will dominate by far. Even in the near term, many developers will start writing in ES6 modules, and transpiling back to ES5. If all modules are strict, then the transpiler will insert the required "use strict" directive, and all is good.

To put another spin on it, how often will we see a class that is outside of any module?

What about node code?

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Thu, Dec 27, 2012 at 12:24 AM, Brendan Eich<brendan at mozilla.com> wrote:

IOW, I want more strict extensions too, but implicitly! Again, having to write "use strict"; itself makes for more sloppy code over time, but new syntax can be its own reward for the new semantics.

Geez I find this tempting. But I cannot agree. Code is read more often than it is written, and ease of opting into strict mode isn't worth the price of making it harder to tell which code is in strict mode. I agree with Kevin's point #3. "function*" and arrow functions, being functions, have function bodies. For "function" functions, they opt into strict if they begin with "use strict".

No, not only by that syntax. They also may be opted-in by their outermost enclosing function that uses such a prologue directive.

That's what makes this less a readability win under your argument. To find the governing "use strict"; in a large program or (real bugs bit ES5 here) concatenation is not easy. One is not "reading" at that point, one is grepping or searching in an editor that can match brackets if not do deeper analysis.

It would be confusing to a reader of code for some functions to do this implicitly.

An outer function having "use strict"; can implicitly do this to an inner function, and rightly so, but at arbitrary distance in KLOCs or other metrics.

So I don't see the argument against "implicit strict" as overriding.

It would not be confusing for readers to not have "function*" or arrow functions available in sloppy mode. When reading sloppy code, these new function forms wouldn't appear without a "use strict" pragma, and so wouldn't raise any new strictness questions for readers.

Again, we want ES6 features such as arrows and generators to be adopted, whether authors can afford to adopt strict mode in enclosing functions or top-level programs, or not. Do not multiply risks.

It's one thing to have arrows and generators be implicitly strict, and get them working without early errors on load and without runtime errors under test.

It's another to say that anyone who wants to use such good new features must migrate the entire enclosing function or program to strict mode. That may be a large top-level script, with legacy issues compounded by concatenation.

Class is an interesting case though, for three reasons.

  1. Its body is not a function body, and so it would be yet more syntax to enable a class to opt into strict mode explicitly.

Right. I don't think we've considered this carefully in TC39 yet.

  1. It is a large-grain abstraction mechanism, much like modules, and often used as the only module-like mechanism in many existing programming languages. (Yes, JavaScript is a different language. But we called it "class" to leverage some of that prior knowledge.)

Won't quibble ;-).

  1. It looks as foreign to old ES3 programmers as does module.

More positive: it looks like a unit of new and stricter code, so it could be strict by fiat, implicitly.

So I recommend no implicit opt-in, except for module (of course) and possibly class. If class does not implicitly opt in, we need to extend the class body syntax to accept a "use strict" pragma.

Good, happy to have support for class bodies implicitly strict!

As for what function forms or heads require explicit opt-in, that hangs on the micro-mode issue. If you're right that we would not make things simpler if these were available only in strict mode, then I agree with your conclusion. More later after I review where these micro-modes ended up, especially the scoping issues on default argument expressions. What's the best thing to read to understand the current state of these? How well does the current draft spec reflect the current agreements?

Allen's latest draft already covers a lot of the function head new-syntax-is-its-own-opt-in (including-extra-strictish-checks ;-).

I do think "let" should only be available in strict mode, rather than the syntactic crazy rules we started to invent at the last meeting.

We should discuss at the next meeting, with more homework to do before then.

In writing this list, I realize that the specific issue that set me off, f-i-b, is a red herring. Because of ES3 practice, everyone will continue to support f-i-b somehow in sloppy mode. If we can get everyone to adopt the block-lexical semantics for sloppy that they have in strict mode, that's simpler than maintaining the current de facto crazy semantics for these in sloppy mode and having them have block lexical semantics in strict code. So I'm on board with evangelizing the problem web sites to fix their f-i-b code.

Evangelization costs, even with volunteer help. It's work. Need to organize it a bit and take all the fun out, and make it matter. More under separate cover.

# Herby Vojčík (12 years ago)

Brendan Eich wrote:

Mark S. Miller wrote:

Class is an interesting case though, for three reasons.

  1. Its body is not a function body, and so it would be yet more syntax to enable a class to opt into strict mode explicitly.

Right. I don't think we've considered this carefully in TC39 yet.

  1. It is a large-grain abstraction mechanism, much like modules, and often used as the only module-like mechanism in many existing programming languages. (Yes, JavaScript is a different language. But we called it "class" to leverage some of that prior knowledge.)

Won't quibble ;-).

  1. It looks as foreign to old ES3 programmers as does module.

More positive: it looks like a unit of new and stricter code, so it could be strict by fiat, implicitly.

So I recommend no implicit opt-in, except for module (of course) and possibly class. If class does not implicitly opt in, we need to extend the class body syntax to accept a "use strict" pragma.

Good, happy to have support for class bodies implicitly strict!

I would like it as well.

# Kevin Smith (12 years ago)

So I don't see the argument against "implicit strict" as overriding.

The main argument against implicit strict, peppered across new syntax, is increased complexity for little gain. In other words, bloat. If you want implicit strict, then do it for module bodies only (in or out-of-line). Anything else: YAGNI.

I'm tellin' ya, no one's going to write any significant non-module code. : )

# Kevin Smith (12 years ago)

What about node code?

Well, node modules are not ES6 modules. They are functions with an implicit head and braces. So implicit strict mode, applied to ES6 modules, would not apply to them.

# Russell Leggett (12 years ago)

On Fri, Dec 28, 2012 at 6:06 AM, Kevin Smith <khs4473 at gmail.com> wrote:

What about node code?

Well, node modules are not ES6 modules. They are functions with an implicit head and braces. So implicit strict mode, applied to ES6 modules, would not apply to them.

Sorry, I should have expanded further - that was my point. Node is a case where I can see classes being used without modules. I imagine native class support will hit v8 soon enough, and I could see people start using them without trying to switch to ES6 modules.

# Bill Frantz (12 years ago)

On 12/27/12 at 11:36 PM, brendan at mozilla.com (Brendan Eich) wrote:

To find the governing "use strict"; in a large program or (real bugs bit ES5 here) concatenation is not easy.

I would want syntax coloring here. Perhaps a light blue background for strict mode and a light pink one for sloppy. Then the letters could continue to be colored as the editor/IDE wishes. YMMV.

Cheers - Bill


Bill Frantz | If the site is supported by | Periwinkle (408)356-8506 | ads, you are the product. | 16345 Englewood Ave www.pwpconsult.com | | Los Gatos, CA 95032

# Kevin Smith (12 years ago)

Sorry, I should have expanded further - that was my point. Node is a case where I can see classes being used without modules. I imagine native class support will hit v8 soon enough, and I could see people start using them without trying to switch to ES6 modules.

Ah - true. They can put a "use strict" at the top if they want that. Honestly, though, won't Node users be the first to start coding in ES6 modules?

# Herby Vojčík (12 years ago)

Kevin Smith wrote:

What about node code?

Well, node modules are not ES6 modules. They are functions with an implicit head and braces. So implicit strict mode, applied to ES6

That implicit head and braces are in the library, though; so if node wanted (and it would be possible somehow), it could replace it with module. Still don't know if exporting / reentrant require could be handled without much fuss.

# François REMY (12 years ago)

Ah - true. They can put a "use strict" at the top if they want that.

It’s also possible that Node.js will just enable strict mode by default (as soon as it’s faster than the non-strict mode, which should happen soon); when they will do so, it will mean that using the non-strict mode will require a switch, not using the strict one. The 1JS strangeness is for browsers, other platforms may just prefer to use versionning and flags.

# Kevin Smith (12 years ago)

That implicit head and braces are in the library, though; so if node wanted

(and it would be possible somehow), it could replace it with module. Still don't know if exporting / reentrant require could be handled without much fuss.

Possible, but not really clean or (I think) satisfactory, due to the inherent difference between functions and proper modules. But that's a topic for another thread...

# Russell Leggett (12 years ago)

On Fri, Dec 28, 2012 at 9:53 AM, Kevin Smith <khs4473 at gmail.com> wrote:

Sorry, I should have expanded further - that was my point. Node is a case

where I can see classes being used without modules. I imagine native class support will hit v8 soon enough, and I could see people start using them without trying to switch to ES6 modules.

Ah - true. They can put a "use strict" at the top if they want that. Honestly, though, won't Node users be the first to start coding in ES6 modules?

I guess we'll see soon enough, but I think there's still going to be a big battle between ES6 modules and node modules and amd/requireJS. Any early adopter types have already probably invested in something, and because the porting isn't always straightforward, I think many will stick with what they've got for a while. I'd honestly really like to start using ES6 modules soon, but I'm still racking my brain for the right way to do it, because there are a lot of features I've built that are not compatible.

# Kevin Smith (12 years ago)

I guess we'll see soon enough, but I think there's still going to be a big battle between ES6 modules and node modules and amd/requireJS. Any early adopter types have already probably invested in something, and because the porting isn't always straightforward, I think many will stick with what they've got for a while. I'd honestly really like to start using ES6 modules soon, but I'm still racking my brain for the right way to do it, because there are a lot of features I've built that are not compatible.

My feeling is that once the module syntax is set, the flood gates will open. Why code any other way at that point?

# David Herman (12 years ago)

On Dec 26, 2012, at 10:56 PM, Brendan Eich <brendan at mozilla.com> wrote:

It does not even contain the word "strict". IIRC (and I asked about this at the last TC39 meeting and got verbal confirmation), the idea of module {...} implying strict mode was latent, or intended. I'm not sure about out of line modules.

At this point, best thing is to summon Dave.

Yes. IIRC, the reason it doesn't explicitly say strict is that it was in the context of "the new ES6 mode" we'd been talking about, which we'd long before agreed would imply strict. But more and more, it has become clear that "the new ES6 mode" is little more than just strict mode + variable checking.

# David Herman (12 years ago)

On Dec 28, 2012, at 3:01 AM, Kevin Smith <khs4473 at gmail.com> wrote:

I'm tellin' ya, no one's going to write any significant non-module code. : )

+9001 (to quote rwaldron)

We should hold the line against any implicit opt-in beyond modules. Mark argues that classes are coarse-grained, but they can easily be significantly finer-grained than modules. In particular, they're an expression form and can be used for tiny little one-offs:

var f = new (class() { m(x) { } })();

Modules are the largest-grain code structuring form, and they are the biggest biggest biggest carrot we have to offer for strict mode.

I'm fine with adding a "use strict"; pragma to classes, but it's also just as easy to place them in a strict context, either by putting them in a module or a strict function.

# Brendan Eich (12 years ago)

David Herman wrote:

On Dec 28, 2012, at 3:01 AM, Kevin Smith<khs4473 at gmail.com> wrote:

I'm tellin' ya, no one's going to write any significant non-module code. : )

+9001 (to quote rwaldron)

We should hold the line against any implicit opt-in beyond modules. Mark argues that classes are coarse-grained, but they can easily be significantly finer-grained than modules. In particular, they're an expression form and can be used for tiny little one-offs:

 var f = new (class() { m(x) { } })();

Modules are the largest-grain code structuring form, and they are the biggest biggest biggest carrot we have to offer for strict mode.

I get nervous when speculations about future adoption ratios or incentives for developers are made without enough data or table-stakes ante'ing (bolded tripled biggest doesn't count as money!).

I've seen Kevin make wildly optimistic assertions about future Node adoption of modules, but from what I know of the "Amish coders" who dominate there (and believe me I am not mocking, there's much to admire about the Amish, farmers and coders!), adoption will be a fight, as Russell suggested.

I'm fine with adding a "use strict"; pragma to classes, but it's also just as easy to place them in a strict context, either by putting them in a module or a strict function.

It's easy to place things in a strict context if you mean place in a module. But per your own argument, outside a module it's much easier to forget to "use strict'; and make sloppy-mode classes.

Same yardstick should apply to all future measure-guesses of adoption and ease of strictness.

If you assume modules are biggest^3 then sure, what you and Kevin surmise will happen is likely: classes appear in modules almost exclusively, and are thereby implicitly strict.

But this assumption does not prove itself, and more bold-*'ed assertions on top make me more skeptical.

I bet modules will be a big carrot. But -- especially if Node does not switch NPM to ES6 modules for a while -- classes could proliferate outside of modules. I do not know and I'm not willing to add a "use strict"; pragma special case to ClassElement on the theory it will be remembered, when our shared theory outside of modules is that it will likely be forgotten. That just does not seem like same-yardstick future-speculative reasoning.

# David Herman (12 years ago)

On Dec 28, 2012, at 12:20 PM, Brendan Eich <brendan at mozilla.com> wrote:

I get nervous when speculations about future adoption ratios or incentives for developers are made without enough data or table-stakes ante'ing (bolded tripled biggest doesn't count as money!).

OK, I've made that same argument recently, I'll take it. I guess what I can retain of that argument is that if modules succeed, then the implicit opt-in will have bought us little.

But even if not, it's not worth proliferating the number of cases that are implicitly strict. Modules are a good place to implicitly opt in to strict mode, because they're a coarse-grained program structuring feature. Classes are finer-grained, especially dynamic classes like in ES6.

Meanwhile we don't need the world to use strict. Modules will reinforce strictness on a large scale; classes provide much less reinforcement, and more complexity. Not worth it.

# Brendan Eich (12 years ago)

David Herman wrote:

OK, I've made that same argument recently, I'll take it. I guess what I can retain of that argument is thatif modules succeed, then the implicit opt-in will have bought us little.

That I agree with (already).

But even ifnot, it's not worth proliferating the number of cases that are implicitly strict.

But why isn't it worth the proliferation cost to get the benefit of strict-by-fiat classes if those proliferate outside of modules?

To answer that, you have to speculate on costs and benefits of strict mode for classes outside of modules, not talk about modules more:

Modules are a good place to implicitly opt in to strict mode, because they're a coarse-grained program structuring feature.

And granularity of class vs. module can't matter under the "even if not" hypothesis we are exploring together in this branch of future-reality:

Classes are finer-grained, especially dynamic classes like in ES6.

The question really is, why have sloppy-mode classes at all? Who wants or needs them?

Meanwhile we don'tneed the world to use strict. Modules will reinforce strictness on a large scale; classes provide much less reinforcement, and more complexity. Not worth it.

(This just rehashes your assumption and the conclusion we agree follows from it!)

# Brandon Benvie (12 years ago)

So to speculate, what are the costs and benefits? Earlier in this thread I said a cost of putting things in strict mode is in increasing the semantic gap between otherwise identical code (besides the pragma), and the cost of not doing so it in any compatibility constraints (such as block scope function decls). To further that, I think the general concensus seems to be that a cost of not putting things in strict-mode only is that it implicitly encourages not using strict-mode, which is not desirable.

The cost above, increasing the semantic gap, doesn't exist when it's about completely new function forms. The costs involved with calling a strict function already exist and are a sunk cost, since in theory any time you use third party code you could be calling into a strict function and all that entails. So I don't see what costs are associated with making new function forms implicitly strict. In fact, I see the reverse: by allowing them to have two modes, you create that very cost same cost. If these new forms only have one mode then they will be simpler than regular function declarations/expressions, along with the added benefits of listed above of enforcing strict mode.

# David Herman (12 years ago)

On Dec 28, 2012, at 12:30 PM, Brendan Eich <brendan at mozilla.com> wrote:

But even ifnot, it's not worth proliferating the number of cases that are implicitly strict.

To answer that, you have to speculate on costs and benefits of strict mode for classes outside of modules, not talk about modules more:

'scuse me for living! ;) I was making a contrast: what's good about modules -- that they are coarse-grained -- is not the case for classes.

Modules are a good place to implicitly opt in to strict mode, because they're a coarse-grained program structuring feature.

And granularity of class vs. module can't matter under the "even if not" hypothesis we are exploring together in this branch of future-reality:

Yes, it can. Let's postulate that modules are a total failure. In addition to my being driven to the drink and moving to Zihuatanejo to run a small beachside hotel, we've failed to use modules as a carrot to bring people to strict mode. Then in that future, I claim that trying additionally to bring people to strict mode by one or more finer-grained mechanisms will not be worth it. It will lead to code that is sometimes strict, sometimes not, and often mixed; and it will lead to a more confusing set of policies that programmers will have to (but often fail to) memorize.

Classes are finer-grained, especially dynamic classes like in ES6.

The question really is, why have sloppy-mode classes at all? Who wants or needs them?

That's easy. If you're programming in sloppy mode, you still want classes. Whether they're strict code is simply less important than whether they exist at all.

Here's another way to put my argument. Let's say you write a program that isn't using modules but is 80% full of classes. I argue that's not reaching 80% of the goal of writing strict code. It's a Pyrrhic almost-victory for strict mode: a confusing mixture of implicitly strict and implicitly sloppy code. There's a difference in kind here, not just degree: a module is very strongly delimited from other code (especially when it occurs in a separate file), whereas a class always intermingles with other code.

# Brendan Eich (12 years ago)

Brandon Benvie wrote:

So I don't see what costs are associated with making new function forms implicitly strict. In fact, I see the reverse: by allowing them to have two modes, you create that very cost same cost. If these new forms only have one mode then they will be simpler than regular function declarations/expressions, along with the added benefits of listed above of enforcing strict mode.

Yes, if new forms with distinct heads are strict-by-fiat, then one could argue that ES6 is simpler. But a counter-argument is that people have to know in hard cases, not just caller calling could-be-strict callee, but when maintaining code and doing things like adding arguments or 'with' uses (not kidding -- latter is early error, former could lead to trouble).

The counter-counter-argument is that usually strict mode is saner and better and the sloppy vs. strict runtime semantic shift (w/o early errors) hard cases should not "make bad law". They should remain hard for the greater good of more strict code over time, due to more modules, classes, generators and arrow functions.

# Brendan Eich (12 years ago)

David Herman wrote:

On Dec 28, 2012, at 12:30 PM, Brendan Eich<brendan at mozilla.com> wrote:

But even ifnot, it's not worth proliferating the number of cases that are implicitly strict. To answer that, you have to speculate on costs and benefits of strict mode for classes outside of modules, not talk about modules more:

'scuse me for living! ;) I was making a contrast: what's good about modules -- that they are coarse-grained -- is not the case for classes.

Point taken, but if we are exploring alternative futures, one you do not want but concede may happen (classes spread outside of modules), we should stick to the path of exploration we're on. Otherwise it seems like you're backing up above that multiverse branch point and arguing for modules prevailing!

Modules are a good place to implicitly opt in to strict mode, because they're a coarse-grained program structuring feature. And granularity of class vs. module can't matter under the "even if not" hypothesis we are exploring together in this branch of future-reality:

Yes, it can. Let's postulate that modules are a total failure. In addition to my being driven to the drink and moving to Zihuatanejo to run a small beachside hotel, we've failed to use modules as a carrot to bring people to strict mode.

A bit extreme, but ok (I'll bartend :-P).

Then in that future, I claim that trying additionally to bring people to strict mode by one or more finer-grained mechanisms will not be worth it. It will lead to code that is sometimes strict, sometimes not, and often mixed; and it will lead to a more confusing set of policies that programmers will have to (but often fail to) memorize.

That's the sticking point. Is that likely greater confusion still not worth the rising tide of strictness, under the classes-prevail hypothesis? I'm not twisting your arm. It could be not worth it. But couldn't it (if classes predominate) win?

Classes are finer-grained, especially dynamic classes like in ES6. The question really is, why have sloppy-mode classes at all? Who wants or needs them?

That's easy. If you're programming in sloppy mode, you still want classes. Whether they're strict code is simply less important than whether they exist at all.

Brandon addressed this. Anyone mixing sloppy and strict (which will become more common as libraries "use strict") has to take care already. You don't know the full call graph, so callees from sloppy code could be strict.

I also disagree that the (uncontroversial) importance of classes existing and being usable from sloppy mode trumps the importance of whether classes are strict by fiat. First, everyone wants classes available in sloppy mode, even Mark. In that light, the importance of classes from sloppy mode is invariant "ground" and we're arguing about the "figure": whether classes should be strict by fiat.

Second, if classes' strictness in ES6 is unimportant in absolute terms we don't need "use strict"; in ClassElement syntax. Yet strictness helps avoid duplicate formals, eval and arguments rebinding/shadowing, and other chestnuts that cannot matter to sloppy consumers of classes. Only the implementor of the class-in-sloppy-mode could use such features. They're "callee-side".

So again: why would we want to make such bad old forms possible in brand new (albeit embedded in sloppy code) classes?

Relative importance doesn't help answer this. My answer is that we do not want bad old slop in classes.

Here's another way to put my argument. Let's say you write a program that isn't using modules but is 80% full of classes. I argue that's not reaching 80% of the goal of writing strict code. It's a Pyrrhic almost-victory for strict mode: a confusing mixture of implicitly strict and implicitly sloppy code.

This is indeed the sticking point.

I call it 80% better than nothing, and I further predict modules won't get to 100 or even 99% soon, and even ignoring new ES6 features, developers will face a mix of strict and slopppy code.

Then the game is momentum and secular up-trend in strict code. In that game, strict-by-fiat is strictly (heh) better.

There's a difference in kind here, not just degree: a module is very strongly delimited from other code (especially when it occurs in a separate file), whereas a class always intermingles with other code.

What do you mean by "intermingle"? See above about caller vs. strict callee. There's no difference that I can see in either source delimiting or runtime caller/callee combinatorics between modules (with function exports) and classes (with methods).

# Kevin Smith (12 years ago)

The question really is, why have sloppy-mode classes at all? Who wants or needs them?

Well, no one, really. But we shouldn't want big invisible switches or any new pragma-haunts either.

You've said that my predictions are "wildly optimistic", and I'm going to have to push back.

Let me, like the Ghost of Christmas Present, take you on a tour of the current state of the art in interoperable javascript modules, on this eve of 2013.

Behold, UMD (Universal Module Definition), the "jewel" of the javascript community:

gist.github.com/4402566

Everyone, and I mean ev-er-y-one, will be ecstatic when this scourge is beaten, burned, scattered, and wiped off the face of the Earth. Sure, Scrooges everywhere will say "Bah humbug! ES6 modules suck!", but it's laugh-out-loud ridiculous to think that anyone, anywhere would choose UMD over ES6 modules.

A standardized module syntax is the #1 needed feature in javascript, bar none. We don't need to worry about adoption.

Well, what about Node and NPM? There's a well-established module system in place which has some apparent incompatibilities with ES6 modules. What to do? Well, Node will move in the direction that it has to move: toward ES6 modules. Championing a legacy module system with well-known problems in the face of ES6 modules, as standardized by EcmaScript, is a non-starter. And ultimately, despite the gnashing of teeth over on Twitter, this will be a good thing for javascript users.

# Brendan Eich (12 years ago)

Kevin Smith wrote:

The question really is, why have sloppy-mode classes at all? Who
wants or needs them?

Well, no one, really. But we shouldn't want big invisible switches or any new pragma-haunts either.

There's no invisible switch. You are assuming something not axiomatic: that new syntax head-forms other than module must inherit sloppy from outer code. That does not follow without more argumentation.

I'm not sure what "pragma-haunts" means. Adding "use strict"; to ClassElement sounds more like that, and I'm clearly arguing against!

You've said that my predictions are "wildly optimistic", and I'm going to have to push back.

Let me, like the Ghost of Christmas Present, take you on a tour of the current state of the art in interoperable javascript modules, on this eve of 2013.

Behold, UMD (Universal Module Definition), the "jewel" of the javascript community:

gist.github.com/4402566

Everyone, and I mean ev-er-y-one, will be ecstatic when this scourge is beaten, burned, scattered, and wiped off the face of the Earth.

Who actually uses this or an equivalent? I see lots of code choosing one or another module/package system but few attempts at dual interop. I haven't see this in the field, but I'm not looking hard.

Sure, Scrooges everywhere will say "Bah humbug! ES6 modules suck!", but it's laugh-out-loud ridiculous to think that anyone, anywhere would choose UMD over ES6 modules.

A standardized module syntax is the #1 needed feature in javascript, bar none. We don't need to worry about adoption.

Well, what about Node and NPM? There's a well-established module system in place which has some apparent incompatibilities with ES6 modules. What to do? Well, Node will move in the direction that it has to move: toward ES6 modules. Championing a legacy module system with well-known problems in the face of ES6 modules, as standardized by EcmaScript, is a non-starter. And ultimately, despite the gnashing of teeth over on Twitter, this will be a good thing for javascript users.

This is all fun, but "ultimately" is a giveaway. Years from now, modules uber alles, you bet. I'm arguing against coupled (multiplied) risk in the near term.

# Kevin Smith (12 years ago)

There's no invisible switch. You are assuming something not axiomatic: that new syntax head-forms other than module must inherit sloppy from outer code. That does not follow without more argumentation.

I guess I'm saying that anything other than inheritance, without the pragma, is an invisible switch.

I'm not sure what "pragma-haunts" means. Adding "use strict"; to

ClassElement sounds more like that, and I'm clearly arguing against!

OK - good!

Who actually uses this or an equivalent? I see lots of code choosing one or another module/package system but few attempts at dual interop. I haven't see this in the field, but I'm not looking hard.

Esprima: ariya/esprima/blob/master/esprima.js Q: kriskowal/q/blob/master/q.js#L29

If you want your code to work in Node+AMD+Whatever that's what you're stuck with.

This is all fun, but "ultimately" is a giveaway. Years from now, modules

uber alles, you bet. I'm arguing against coupled (multiplied) risk in the near term.

I'm glad to be entertaining : )

And see your point about multiplied risk - I just don't think there's much risk of non-adoption of modules in the near term (year and a half?).

# Brendan Eich (12 years ago)

Kevin Smith wrote:

There's no invisible switch. You are assuming something not
axiomatic: that new syntax head-forms other than module must
inherit sloppy from outer code. That does not follow without more
argumentation.

I guess I'm saying that anything other than inheritance, without the pragma, is an invisible switch.

  1. Except for module.

  2. Non-locality of "use strict" in the medium-to-large makes for an effectively invisible, or at least hard to see as in effect, switch.

I'm not sure what "pragma-haunts" means. Adding "use strict"; to
ClassElement sounds more like that, and I'm clearly arguing against!

OK - good!

So are you in favor of class body as strict by default?

Who actually uses this or an equivalent? I see lots of code
choosing one or another module/package system but few attempts at
dual interop. I haven't see this in the field, but I'm not looking
hard.

Esprima: ariya/esprima/blob/master/esprima.js Q: kriskowal/q/blob/master/q.js#L29

If you want your code to work in Node+AMD+Whatever that's what you're stuck with.

There must be a lot of Node-only modules that I tend to look at.

This is all fun, but "ultimately" is a giveaway. Years from now,
modules uber alles, you bet. I'm arguing against coupled
(multiplied) risk in the near term.

I'm glad to be entertaining : )

And see your point about multiplied risk - I just don't think there's much risk of non-adoption of modules in the near term (year and a half?).

I hope you're right, but is after a year and a half really what you meant by "ultimately"? I see a fight, not taking sides or blaming anyone. JS is big enough and multi-paradigm enough that multiple schools of thought already hold sway over large factions of developers. The amount of legacy code is quite large, too.

This all adds up in my view to an unclear setting in which to place all bets only on module as implicitly strict.

# Kevin Smith (12 years ago)
  1. Except for module.

Right.

  1. Non-locality of "use strict" in the medium-to-large makes for an effectively invisible, or at least hard to see as in effect, switch.

Mmmm.. maybe.

So are you in favor of class body as strict by default?

You mean as always strict? I wasn't when I wrote that, but now I'm thinking that "classes are always strict" would probably be acceptable. I would definitely hold the line at modules and classes, though.

There must be a lot of Node-only modules that I tend to look at.

Well, that'll rot your brain! : P

I hope you're right, but is after a year and a half really what you meant

by "ultimately"? I see a fight, not taking sides or blaming anyone. JS is big enough and multi-paradigm enough that multiple schools of thought already hold sway over large factions of developers. The amount of legacy code is quite large, too.

Sheesh - I tried desperately to bridge those gaps back in 2010 when I was into CommonJS. Blast from the past:

groups.google.com/d/topic/nodejs-dev/d2zZy9-E8mE/discussion

Oh well...

It's really encouraging to see the level of commitment to good design here on this list and on the committee in general. Good design will prevail - I'm not worried!

# Axel Rauschmayer (12 years ago)

Add me to the list of people who are overjoyed when this AMD vs. CJS/Node.js travesty is over. That alone is a good answer if people ask: “What can ES6 modules do that current module systems can’t” – it will (most probably) be a common standard.

So are you in favor of class body as strict by default?

You mean as always strict? I wasn't when I wrote that, but now I'm thinking that "classes are always strict" would probably be acceptable. I would definitely hold the line at modules and classes, though.

Right. “Smaller” constructs (arrow functions, array comprehensions, generator expressions, ...) might indeed be too fine-grained. But if you work with coarse-grained units then switching to newer semantics by default seems reasonable. It’s new code, after all.

# Andreas Rossberg (12 years ago)

I haven't replied to this thread yet, because I feel that I already made all the same arguments repeatedly to no avail. ;) However, let me reiterate one particular observation, which is that IMHO much of the discussion (and decision making) around 1JS, modes, and opt-ins is just mistargeted.

Namely, it is primarily based on the expectations and needs of current users. Users that are aware of what's ES3 or 5 and who are about to investigate what's new in ES6. To those users, design choices like making new constructs opt into strict mode by default will not seem a big deal, even natural.

But that group will be irrelevant after a relatively short time of transition!

ES6+ will stay much longer (at least that's what we are working for). Consequently, what should take precedence are the expectations and needs of future users of ES. Those who will come to ES6+ without knowing nor caring about the colorful history of its earlier versions. For them, having various features locally change the semantics of unrelated constructs will be surprising at best. It means having to remember a seemingly random set of rules for what semantics is active where.

The more such rules there are, and the more fine-grained they are, the less readable code becomes, and the more error-prone programming and, particularly, refactoring will be -- not just for the current generation of ES programmers, but for all generations to come. IMHO, that is the wrong trade-off entirely.

# Axel Rauschmayer (12 years ago)

I’m sympathetic to both sides of this argument. How would you handle things?

# Andreas Rossberg (12 years ago)

On 29 December 2012 14:51, Axel Rauschmayer <axel at rauschma.de> wrote:

I’m sympathetic to both sides of this argument. How would you handle things?

Ideally? Backing out of the whole 1JS marketing maneuver? In the long run, I see it as more harmful than helpful, as it inevitably leads to complexity creep, subtle mode mixtures, and refactoring hazards that are there to stay for eternity. Instead, just make all new features strict-mode only and be done with it.

But I've accepted that I am in the minority with that opinion, and it's too late anyway. Short of that, at least hold the line with modules as the only implicit opt-in. But in reality I'm pretty sure that we will give in to extending the list at some point, if not in ES6 then in ES7.

# Brendan Eich (12 years ago)

Andreas Rossberg wrote:

I haven't replied to this thread yet, because I feel that I already made all the same arguments repeatedly to no avail. ;) However, let me reiterate one particular observation, which is that IMHO much of the discussion (and decision making) around 1JS, modes, and opt-ins is just mistargeted.

Could be, let's see.

Namely, it is primarily based on the expectations and needs of current users. Users that are aware of what's ES3 or 5 and who are about to investigate what's new in ES6. To those users, design choices like making new constructs opt into strict mode by default will not seem a big deal, even natural.

Glad to hear some concurrence.

But that group will be irrelevant after a relatively short time of transition!

Who knows? "Relatively short time" will be measured in units of years, though.

ES6+ will stay much longer (at least that's what we are working for). Consequently, what should take precedence are the expectations and needs of future users of ES. Those who will come to ES6+ without knowing nor caring about the colorful history of its earlier versions. For them, having various features locally change the semantics of unrelated constructs

Whoa.

Who ever proposed that? It seems a misunderstanding. No one is saying that, e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

So what exactly are you referring to here, in the way of a live proposal?

# Brendan Eich (12 years ago)

Andreas Rossberg wrote:

On 29 December 2012 14:51, Axel Rauschmayer<axel at rauschma.de> wrote:

I’m sympathetic to both sides of this argument. How would you handle things?

Ideally? Backing out of the whole 1JS marketing maneuver?

It's not just marketing surface, but lack of version= substance. How do you propose backing out of that? Defining RFC4329 application/javascript and application/ecmascript ;version= parameter values and telling people to write script tags using those types?

In the long run, I see it as more harmful than helpful, as it inevitably leads to complexity creep, subtle mode mixtures,

Note the V8 team (via MarkM) rightly prefigured 1JS by asking for "no more modes" several years ago. Now you want explicit modes? The world turns...

and refactoring hazards that are there to stay for eternity. Instead, just make all new features strict-mode only and be done with it.

Let's be clear about the refactoring hazards. They do not involve early errors. So the only issues are the runtime semantic changes:

  • The arguments object in a strict function not aliasing formal parameters.

  • Poison pill properties on strict function objects.

  • Anything else I'm forgetting.

Is this really that bad in the way of refactoring hazards? Anyone refactoring from old to ES6 or later code should get rid of arguments. The poison pill properties may be needed so that means don't refactor this function, leave it in sloppy mode using function syntax.

What's the big hazard I'm missing?

But I've accepted that I am in the minority with that opinion, and it's too late anyway. Short of that, at least hold the line with modules as the only implicit opt-in.

There's a case for class bodies as implicitly strict, you can't dismiss it with generalities about refactoring hazards in my book :-P. Care to deal with the specific pro-strict-class argument?

But in reality I'm pretty sure that we will give in to extending the list at some point, if not in ES6 then in ES7.

I say all new forms with distinct heads and code-bearing bodies should be strict-only.

# Brendan Eich (12 years ago)

Brendan Eich wrote:

subtle mode mixtures,

I don't buy this one either. We have ES5 sloppy and strict, they mix only statically, with well-defined rules based on "use strict"; (which is not a readability trump card to throw, as discussed).

Any dynamic mixing is at the function call boundary.

Now, consider modules, classes, generators, and arrows:

  • modules export functions, which are strict by definition under 1JS as elaborated.

  • classes define prototype methods (possibly static methods in future) and possibly a constructor.

  • generator functions are a kind of function.

  • arrows are a kind of function.

In all these cases, we have static source delimiting, no mode mixing. In all these cases, we have functions as the smallest units of abstraction. These already may be strict or sloppy per ES5, at runtime.

Furthermore, all four bullets need definite semantics in ES6. We have to say what poison pill properties, what rules for duplicate formals, etc. are. There could be some "spec reuse" argument for factoring such that strict mode decides these things, but with novel syntax in play, that is not an overriding argument against strict-by-fiat.

Allen has already started spec'ing some of these things. He should weigh in on the "spec reuse" situation, but my point here is that strict-by-fiat-for-novel-bodies as I advocate does not create new "subtle mode mixtures".

Yes, one won't see "use strict"; at the front of function bodies in these four bulleted cases. So what? One often has to hunt thousands of lines up, and match braces of module-pattern IIFEs, to know whether a given function is in strict mode anyway.

# Mark S. Miller (12 years ago)

On Sat, Dec 29, 2012 at 1:06 PM, Brendan Eich <brendan at mozilla.com> wrote:

Andreas Rossberg wrote:

I haven't replied to this thread yet, because I feel that I already made all the same arguments repeatedly to no avail. ;) However, let me reiterate one particular observation, which is that IMHO much of the discussion (and decision making) around 1JS, modes, and opt-ins is just mistargeted.

Could be, let's see.

Namely, it is primarily based on the expectations and needs of current users. Users that are aware of what's ES3 or 5 and who are about to investigate what's new in ES6. To those users, design choices like making new constructs opt into strict mode by default will not seem a big deal, even natural.

Glad to hear some concurrence.

But that group will be irrelevant after a relatively short time of transition!

Who knows? "Relatively short time" will be measured in units of years, though.

ES6+ will stay much longer (at least that's what we are working for). Consequently, what should take precedence are the expectations and needs of future users of ES. Those who will come to ES6+ without knowing nor caring about the colorful history of its earlier versions. For them, having various features locally change the semantics of unrelated constructs

Whoa.

Who ever proposed that? It seems a misunderstanding. No one is saying that, e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

This is an example of the micro-modes issue. If optional, rest, and/or destructuring needs to enforce no duplicates, then we have two choices:

  1. Make these features available only in strict code, which doesn't require any new special case -- since strict already bans duplicate parameter names.

  2. Make a micro-mode, adding yet additional mode switching in order to supposedly avoid the complexity of dealing with one mode switch.

By our previous criteria, #1 is obviously simpler than #2.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Sat, Dec 29, 2012 at 1:06 PM, Brendan Eich<brendan at mozilla.com> wrote:

Who ever proposed that? It seems a misunderstanding. No one is saying that, e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

This is an example of the micro-modes issue. If optional, rest, and/or destructuring needs to enforce no duplicates, then we have two choices:

  1. Make these features available only in strict code, which doesn't require any new special case -- since strict already bans duplicate parameter names.

Agree so far.

  1. Make a micro-mode, adding yet additional mode switching in order to supposedly avoid the complexity of dealing with one mode switch.

No, you are using micro-mode as an epithet without actually defining it in a meaningfully different way from "new semantics for new syntax".

Are arrow functions, syntax and definite semantics, a "micro-mode"? If not, why not? I suspect you are using a mental desugaring spec but there's no such spec. Allen has to deal with whether arrows have [[Construct]] (we decided no, because |this| is bound to outer |this|). Is that a "micro-mode"? I say no.

By our previous criteria, #1 is obviously simpler than #2.

I dispute that. The complexity to count is user-facing, not spec-internal or mental-desugaring or other invisible complexity. Users need to know about arrows when writing them. When calling, not so much (one cannot assume all functions are constructors, even in ES1 [builtins]).

Let's try to get to an apples-to-apples user-facing complexity metric, and leave the stuff under the spec hood out.

# Mark S. Miller (12 years ago)

On Sat, Dec 29, 2012 at 1:26 PM, Brendan Eich <brendan at mozilla.com> wrote:

Mark S. Miller wrote:

On Sat, Dec 29, 2012 at 1:06 PM, Brendan Eich<brendan at mozilla.com> wrote:

Who ever proposed that? It seems a misunderstanding. No one is saying that,

e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

This is an example of the micro-modes issue. If optional, rest, and/or destructuring needs to enforce no duplicates, then we have two choices:

  1. Make these features available only in strict code, which doesn't require any new special case -- since strict already bans duplicate parameter names.

Agree so far.

  1. Make a micro-mode, adding yet additional mode switching in order to supposedly avoid the complexity of dealing with one mode switch.

No, you are using micro-mode as an epithet without actually defining it in a meaningfully different way from "new semantics for new syntax".

If I have a function

function foo(w, x, y) {
  var [a, b] = y;
  // use of a,b but not y in rest of body
}

and I change it to

function foo(w, x, [a, b]) {
  // use of a,b but not y in rest of body
}

I have preserved its meaning. The change seems local to the individual parameter. But if I have a function

function foo(x, x, y) {
  var [a, b] = y;
  // use of a,b but not y in rest of body
}

and I change it to

function foo(x, x, [a, b]) {
  // use of a,b but not y in rest of body
}

now my second function is rejected. This demonstrates the "mode-nature" if you will of this rule. The rejection must be explained by a function-wide change of what the language accepts, even though I changed only one parameter.

OTOH, if destructuring is accepted only in strict code, then the rejection of destructuring is explained only by strictness rules. In strict code, the rejection of duplicate parameters is explained only by strictness rules, and applies to both functions above. No micro-modes in sight.

# Kevin Smith (12 years ago)

I gotta say, I'm in agreement with Mark (and even Andreas) here. 1JS, under all modes just isn't going to work (let[x] = y proves that). And keeping track of what's allowed under which mode (and why) could get complicated and difficult to explain.

But what about this?

One JS, Under strict mode, With awesome for all?

Sounds good to me!

# Brandon Benvie (12 years ago)

Put everything new in ES6 as implicit opt-in for strict mode? It certainly is the simplest of all options, both for implementors and users. It also removes the "big enough carrot" problem. Any individual feature may not be enough of a carrot to sway a user, and taken as one by one choice, might leave room for devs to pick and choose around strict mode (if there ends up being some perceived difficulty or annoyance factor). But I can't imagine anyone opting out of everything ES6 provides just to avoid strict mode. The only reason people are likely to avoid everything in ES6 is compat concerns which is orthaganol to strict mode.

Or something like require all ES6 features be inside modules, which accomplishes the same thing. I know I saw this discussion before, or something like it, but wasn't able to locate it.

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

On Sat, Dec 29, 2012 at 1:26 PM, Brendan Eich<brendan at mozilla.com> wrote:

Mark S. Miller wrote:

  1. Make a micro-mode, adding yet additional mode switching in order to supposedly avoid the complexity of dealing with one mode switch. No, you are using micro-mode as an epithet without actually defining it in a meaningfully different way from "new semantics for new syntax".

If I have a function

 function foo(w, x, y) {
   var [a, b] = y;
   // use of a,b but not y in rest of body
 }

and I change it to

 function foo(w, x, [a, b]) {
   // use of a,b but not y in rest of body
 }

I have preserved its meaning. The change seems local to the individual parameter. But if I have a function

 function foo(x, x, y) {

Yes, but let me interject: no one does this. It's insane. A latent bug or a quirk that deserves an early error.

   var [a, b] = y;
   // use of a,b but not y in rest of body
 }

and I change it to

 function foo(x, x, [a, b]) {
   // use of a,b but not y in rest of body
 }

now my second function is rejected.

Yes, with an early error.

Since no one does duplicate formal parameter in practice, this early error is a good thing (tm).

This demonstrates the "mode-nature" if you will of this rule.

Rather, new syntax gets new semantics.

We've shipped this for years in SpiderMonkey. I believe Rhino matches. No one uses duplicate formals, so no one has ever complained.

The rejection must be explained by a function-wide change of what the language accepts,

No, not function-wide! Purely function-head, more specifically the parameter list.

even though I changed only one parameter.

Parameter changes in ES6 have effects on the list. We don't allow more than one rest parameter at the end, for example. Given

function f(a, b, ...r) {...}

If I try adding another ellipsis:

function f(a, ...b, ...r) {...}

I get an early error. Another good thing(tm), and no less local than destructuring parameters banning duplicate params.

OTOH, if destructuring is accepted only in strict code, then the rejection of destructuring is explained only by strictness rules.

"rejection of duplicate parameters"

Yes, that's the way to explain it via (1). And you are right that the condition for rejection of duplicate formals becomes more than "in strict code". It has to be "in strict mode || destructuring present in parameter list".

However, since duplicate formals are a do-not-want, always-a-bug, freakish rarity bestowed on ES1 during standardization, this extra disjunct is a spec-internal complexity, not anything users must worry about.

I'm prepared to give up on the ban of duplicate formals when destructuring parameters are present, if that will get rid of your objection to "micro-modes". I don't recall anything else like this case. We arrived at it mainly to simplify implementation in SpiderMonkey, but again: users do not notice because no one uses duplicate formals.

Are arrow functions, syntax and definite semantics, a "micro-mode"? If not, why not? I suspect you are using a mental desugaring spec but there's no such spec. Allen has to deal with whether arrows have [[Construct]] (we decided no, because |this| is bound to outer |this|). Is that a "micro-mode"? I say no.

Did you have a thought here? It may be we're arguing only about the "destructuring parameter bans duplicate parameters" special case.

# Mark S. Miller (12 years ago)

On Sat, Dec 29, 2012 at 5:16 PM, Brendan Eich <brendan at mozilla.com> wrote:

I'm prepared to give up on the ban of duplicate formals when destructuring parameters are present, if that will get rid of your objection to "micro-modes". I don't recall anything else like this case. We arrived at it mainly to simplify implementation in SpiderMonkey, but again: users do not notice because no one uses duplicate formals.

Are arrow functions, syntax and definite semantics, a "micro-mode"? If not, why not? I suspect you are using a mental desugaring spec but there's no such spec. Allen has to deal with whether arrows have [[Construct]] (we decided no, because |this| is bound to outer |this|). Is that a "micro-mode"? I say no.

Did you have a thought here? It may be we're arguing only about the "destructuring parameter bans duplicate parameters" special case.

If duplicate formals are the only such case, then I agree that the fear of micro-mode is a non-issue. Do we have an accurate record of the scoping of default value expressions? How about the interaction of head scope and top body scope? I recall there were problems here, but I'd need to review our decisions to see if they smell of more micro-modes.

# Domenic Denicola (12 years ago)

Duplicate parameters are quite common in the following case:

callSomething(function (_, _, whatIActuallyCareAbout) {});

From: Brendan Eich<mailto:brendan at mozilla.com> Sent: ?12/?29/?2012 20:16 To: Mark S. Miller<mailto:erights at google.com> Cc: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org> Subject: Re: excluding features from sloppy mode

Mark S. Miller wrote:

On Sat, Dec 29, 2012 at 1:26 PM, Brendan Eich<brendan at mozilla.com> wrote:

Mark S. Miller wrote:

  1. Make a micro-mode, adding yet additional mode switching in order to supposedly avoid the complexity of dealing with one mode switch. No, you are using micro-mode as an epithet without actually defining it in a meaningfully different way from "new semantics for new syntax".

If I have a function

 function foo(w, x, y) {
   var [a, b] = y;
   // use of a,b but not y in rest of body
 }

and I change it to

 function foo(w, x, [a, b]) {
   // use of a,b but not y in rest of body
 }

I have preserved its meaning. The change seems local to the individual parameter. But if I have a function

 function foo(x, x, y) {

Yes, but let me interject: no one does this. It's insane. A latent bug or a quirk that deserves an early error.

   var [a, b] = y;
   // use of a,b but not y in rest of body
 }

and I change it to

 function foo(x, x, [a, b]) {
   // use of a,b but not y in rest of body
 }

now my second function is rejected.

Yes, with an early error.

Since no one does duplicate formal parameter in practice, this early error is a good thing (tm).

This demonstrates the "mode-nature" if you will of this rule.

Rather, new syntax gets new semantics.

We've shipped this for years in SpiderMonkey. I believe Rhino matches. No one uses duplicate formals, so no one has ever complained.

The rejection must be explained by a function-wide change of what the language accepts,

No, not function-wide! Purely function-head, more specifically the parameter list.

even though I changed only one parameter.

Parameter changes in ES6 have effects on the list. We don't allow more than one rest parameter at the end, for example. Given

function f(a, b, ...r) {...}

If I try adding another ellipsis:

function f(a, ...b, ...r) {...}

I get an early error. Another good thing(tm), and no less local than destructuring parameters banning duplicate params.

OTOH, if destructuring is accepted only in strict code, then the rejection of destructuring is explained only by strictness rules.

"rejection of duplicate parameters"

Yes, that's the way to explain it via (1). And you are right that the condition for rejection of duplicate formals becomes more than "in strict code". It has to be "in strict mode || destructuring present in parameter list".

However, since duplicate formals are a do-not-want, always-a-bug, freakish rarity bestowed on ES1 during standardization, this extra disjunct is a spec-internal complexity, not anything users must worry about.

I'm prepared to give up on the ban of duplicate formals when destructuring parameters are present, if that will get rid of your objection to "micro-modes". I don't recall anything else like this case. We arrived at it mainly to simplify implementation in SpiderMonkey, but again: users do not notice because no one uses duplicate formals.

Are arrow functions, syntax and definite semantics, a "micro-mode"? If not, why not? I suspect you are using a mental desugaring spec but there's no such spec. Allen has to deal with whether arrows have [[Construct]] (we decided no, because |this| is bound to outer |this|). Is that a "micro-mode"? I say no.

Did you have a thought here? It may be we're arguing only about the "destructuring parameter bans duplicate parameters" special case.

/be


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-------------- next part -------------- An HTML attachment was scrubbed... URL: esdiscuss/attachments/20121230/2ec971e9/attachment-0001

# Brendan Eich (12 years ago)

Domenic Denicola wrote:

Duplicate parameters are quite common in the following case:

callSomething(function (_, _, whatIActuallyCareAbout) {});

I've never seen that in JS. In ML, sure.

Have you any links to cite?

# Kevin Smith (12 years ago)

The more I think about this, the more convinced I get that all new syntax and breaking changes (where possible) should be strict-mode only. In retrospect, let[x] = y; changed everything. Here's why I think "1JS under strict" is the best solution:

  • How exactly would one teach that classes, arrows, etc. are all available in sloppy mode, but "let" is not? The reason is obscure for a casual user. It's going to seem arbitrary. On the other hand, "1JS under strict" is quite easy to teach.

  • It creates a clean, linear evolution for javascript syntax: ES3 > ES5

strict > ES6 > ES7.

  • It eliminates the so-called "micro-modes" in function heads.

  • It gets everyone moving in the same direction: strict mode.

  • It eliminates subjective questions about what constructs should be implicitly strict.

To be clear, I'm proposing that:

  1. All new syntax and breaking changes (where possible) are strict-mode only.
  2. Modules and only modules are implicitly strict.

Why not?

Lurkers out there! Would anyone be opposed to opting-in to new ES6 syntax by either (a) "use strict" or (b) modules?

# Brendan Eich (12 years ago)

Kevin Smith wrote:

The more I think about this, the more convinced I get that all new syntax and breaking changes (where possible) should be strict-mode only. In retrospect, let[x] = y; changed everything. Here's why I think "1JS under strict" is the best solution:

  • How exactly would one teach that classes, arrows, etc. are all available in sloppy mode, but "let" is not? The reason is obscure for a casual user. It's going to seem arbitrary. On the other hand, "1JS under strict" is quite easy to teach.

Ease of teaching != successfully imparted knowledge at scale. Sorry, but it's true. People don't use "use strict"; at top level enough, and teaching them all will take time. Even then, because of the Law of Least Effort, it'll be left out.

This is the major objection some of us keep raising, and you don't engage with it. Please do!

  • It creates a clean, linear evolution for javascript syntax: ES3 > ES5 strict > ES6 > ES7.

I would use < for that relation, but it's not a subset relation due to the non-early-error, runtime-semantic-shifts of ES5 strict.

Also, enough pretty (if inaccurate) diagrams! User-facing complexity, developer ergonomics, usability matter more than Platonic prettiness. There, I said it :-P.

  • It eliminates the so-called "micro-modes" in function heads.

A canard, or at most a quibble about banning duplicate formals in the present of destructuring, which I am prepared to negotiate away. Please don't repeat it carelessly.

  • It gets everyone moving in the same direction: strict mode.

In your dreams, but in reality the sprawl is large and in several direction.

  • It eliminates subjective questions about what constructs should be implicitly strict.

There's nothing subjective about such questions, any more than your contentions about strict mode being objective. In practice people will not use strict when they might, and making ES6 features available only under "use strict" will, ceteris paribus, lead to less adoption of ES6 than otherwise.

To be clear, I'm proposing that:

  1. All new syntax

New syntax is not a breaking change (as you use that phrase).

and breaking changes (where possible)

Why the "(where possible)"?

are strict-mode only.

If you believe in strict mode so strongly, why not make all new syntax with a body-form be implicitly strict in that body's code?

  1. Modules and only modules are implicitly strict.

Whew! You seemed to throw this out in your lede, really till here.

Why not?

Lurkers out there! Would anyone be opposed to opting-in to new ES6 syntax by either (a) "use strict" or (b) modules?

I know, you're tired of hearing from me. I'll subside for a while. However, you know there are issues with strict mode, not all "superstition". Ignoring them, pretending they do not hamper adoption, dodges the central objection to your proposal: that by yoking ES6 feature adoption to strict mode adoption, you multiply risks and reduce ES6 adoption.

# Brendan Eich (12 years ago)

Kevin Smith wrote:

The more I think about this, the more convinced I get that all new syntax and breaking changes (where possible) should be strict-mode only ...

  1. All new syntax and breaking changes (where possible) are strict-mode only.
  2. Modules and only modules are implicitly strict.

(2) is not what (1) says, ignoring the mysterious "(where possible)" loophole.

Your lede has the loophole too and talks about ease of teaching. I smell a rat! Teaching people a simplified but not-quite-true story is useful. It's done all the time. But that is teaching, not language design. The full truth has the module loophole. Why? Why not class bodies too?

The teaching myth in your lede and up till near the end does not justify the loophole being only big enough to let module through. A general slippery slope preference for one exception rather than N > 1

exceptions, that works a bit better, but it is still a bit of special-pleading.

As promised subsiding. I just had to follow up because on re-reading, I noticed the teaching trick you pulled off. It's a good trick, again

# Domenic Denicola (12 years ago)

Sadly no, and can't quite seem to get any of the various code-searches on the internet working. It would be worth doing one of those web-crawling experiments we see from time to time, though.

# Domenic Denicola (12 years ago)

From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Brendan Eich Sent: Sunday, December 30, 2012 00:06

by yoking ES6 feature adoption to strict mode adoption, you multiply risks and reduce ES6 adoption.

I'd like to lend a little bit of defense to Kevin's ideas here. Namely, it seems easy to me to imagine the following:

  • "Oh cool, ES6 is in $MY_FAVORITE_JS_ENVIRONMENT!"
  • "Awesome lemme insert some arrow functions to clean up all these map and filter arguments"
  • "What's that, Mr. Compiler? You won't let me use arrow functions unless I put 'use strict' at the top of my file?"
  • "OK, whatever, that seems lame, but arrow functions are worth it."

This is of course predicated on the code in question not being affected by the breaking changes of strict mode, which is probably true of most code written by early adopters today.

To be clear, there's obviously a lot of subtle issues here, as Brendan has pointed out. I do find it somewhat unlikely though, that if strict mode was required for anything ES6-ish, people would give up their new toys rather than point a pragma at the top of their file.

(Although, as I write that last sentence, I realize this isn't much different than suggested use version 6 :-/)

# Kevin Smith (12 years ago)

Ease of teaching != successfully imparted knowledge at scale. Sorry, but it's true. People don't use "use strict"; at top level enough, and teaching them all will take time. Even then, because of the Law of Least Effort, it'll be left out.

This is the major objection some of us keep raising, and you don't engage with it. Please do!

Sure - my answer is: modules, classes, arrows, and templates. Those carrots are so sweet that no developer will be able to resist them. I tend to overstate, I know, but they are game-changers!

  • It creates a clean, linear evolution for javascript syntax: ES3 > ES5

strict > ES6 > ES7.

I would use < for that relation, but it's not a subset relation due to the non-early-error, runtime-semantic-shifts of ES5 strict.

Yep - should have been "<", and it's loose as you say.

Also, enough pretty (if inaccurate) diagrams! User-facing complexity, developer ergonomics, usability matter more than Platonic prettiness. There, I said it :-P.

Yep - elegance is my siren song. But if there is a place for Platonic prettiness, then it must be in the language itself.

  • It eliminates the so-called "micro-modes" in function heads.

A canard, or at most a quibble about banning duplicate formals in the present of destructuring, which I am prepared to negotiate away. Please don't repeat it carelessly.

Fair enough.

  • It gets everyone moving in the same direction: strict mode.

In your dreams, but in reality the sprawl is large and in several direction.

Well, my take is that people just like to talk tough.

  • It eliminates subjective questions about what constructs should be

implicitly strict.

There's nothing subjective about such questions, any more than your contentions about strict mode being objective. In practice people will not use strict when they might, and making ES6 features available only under "use strict" will, ceteris paribus, lead to less adoption of ES6 than otherwise.

Again, the sweetness of the carrots tell me otherwise.

and breaking changes (where possible)

Why the "(where possible)"?

Because not being a runtime implementor (not yet anyway), I can't comment on where it might be impractical to have bifurcated semantics.

If you believe in strict mode so strongly, why not make all new syntax with

a body-form be implicitly strict in that body's code?

Platonic prettiness : )

  1. Modules and only modules are implicitly strict.

Whew! You seemed to throw this out in your lede, really till here.

Modules are the lynchpin!

I know, you're tired of hearing from me.

Are you kidding? Not one bit!

I'll subside for a while. However, you know there are issues with strict mode, not all "superstition". Ignoring them, pretending they do not hamper adoption, dodges the central objection to your proposal: that by yoking ES6 feature adoption to strict mode adoption, you multiply risks and reduce ES6 adoption.

I understand the concern, really. But I would say that given the sweetness of the carrots, it rather eliminates the risk of strict mode non-adoption.

# Kevin Smith (12 years ago)
  1. All new syntax and breaking changes (where possible) are strict-mode

only. 2) Modules and only modules are implicitly strict.

(2) is not what (1) says, ignoring the mysterious "(where possible)" loophole.

You're really sharp! Notice that I didn't specify in or out-of-line modules there. Originally, I was going to close the loophole by saying that only out-of-line modules get implicit strict, but I waffled... Nice catch!

# Brandon Benvie (12 years ago)

I believe the only major factors in usage uptake for ES6 will be in the ever present need for backwards compatibility, and educating developers on what new tools exist. Imdo not believe having a "use strict" gatekeeper at the front of the ES6 bonanza would not be a motivating factor in turning people away.

"I really wish I could use destructuring and arrow functions and generators and iterators and...a dozen more carrots, but this strict mode thing is just a bridge too far."

I cannot see that thought process actually going through anyone's mind.

# Andreas Rossberg (12 years ago)

On 29 December 2012 22:06, Brendan Eich <brendan at mozilla.com> wrote:

Andreas Rossberg wrote:

ES6+ will stay much longer (at least that's what we are working for). Consequently, what should take precedence are the expectations and needs of future users of ES. Those who will come to ES6+ without knowing nor caring about the colorful history of its earlier versions. For them, having various features locally change the semantics of unrelated constructs

Whoa.

Who ever proposed that? It seems a misunderstanding. No one is saying that, e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

We are discussing it for classes right now, and it has been on the table for other features (such as arrows or generators) several times, if my memory serves me right.

# Andreas Rossberg (12 years ago)

On 29 December 2012 22:11, Brendan Eich <brendan at mozilla.com> wrote:

Andreas Rossberg wrote:

On 29 December 2012 14:51, Axel Rauschmayer<axel at rauschma.de> wrote:

I’m sympathetic to both sides of this argument. How would you handle things?

Ideally? Backing out of the whole 1JS marketing maneuver?

It's not just marketing surface, but lack of version= substance. How do you propose backing out of that? Defining RFC4329 application/javascript and application/ecmascript ;version= parameter values and telling people to write script tags using those types?

As I said: make everything available in strict mode.

In the long run, I see it as more harmful than helpful, as it inevitably leads to complexity creep, subtle mode mixtures,

Note the V8 team (via MarkM) rightly prefigured 1JS by asking for "no more modes" several years ago. Now you want explicit modes? The world turns...

I'm sure no one had the current state of affairs in mind. My argument is (and has been a year ago), that factually, 1JS means more modes (which is why I called the 1JS tag "marketing"). And that is user-facing complexity.

I wish I had made a list, but IIRC over the last few meetings we have spend a significant and increasing amount of time discussing problems with new features and sloppy mode interaction. You can brush that off as being only spec or implementation complexity. But I disagree. Any spec complexity will also be user-facing complexity too at some point, e.g. if your program does not work as expected.

Let's be clear about the refactoring hazards. They do not involve early errors. So the only issues are the runtime semantic changes:

  • The arguments object in a strict function not aliasing formal parameters.

  • Poison pill properties on strict function objects.

  • Anything else I'm forgetting.

Is this really that bad in the way of refactoring hazards? Anyone refactoring from old to ES6 or later code should get rid of arguments.

I'm surprised you're asking this, because you have pointed out repeatedly in previous meetings that there are serious hazards. ;)

There's a case for class bodies as implicitly strict, you can't dismiss it with generalities about refactoring hazards in my book :-P. Care to deal with the specific pro-strict-class argument?

It's complexity creep. I don't think we will stop there. Boiling the frog.

[Sorry for being brief, but I'm off to a 2-week trip in about 2 hours and haven't packed yet :). I'll be off-line during that time, btw, so unfortunately won't be able to follow the discussion further.]

# Andreas Rossberg (12 years ago)

On 30 December 2012 02:31, Mark S. Miller <erights at google.com> wrote:

If duplicate formals are the only such case, then I agree that the fear of micro-mode is a non-issue. Do we have an accurate record of the scoping of default value expressions? How about the interaction of head scope and top body scope? I recall there were problems here, but I'd need to review our decisions to see if they smell of more micro-modes.

Yes, there were problems with duplicate parameters vs defaults. There also is the sloppy-mode-arguments-object vs destructuring issue. And 'let' syntax. These are just some of the things that came up at the last meeting alone.

# Claus Reinke (12 years ago)

Ease of teaching != successfully imparted knowledge at scale. Sorry, but it's true. People don't use "use strict"; at top level enough, and teaching them all will take time. Even then, because of the Law of Least Effort, it'll be left out.

This is the major objection some of us keep raising, and you don't engage with it. Please do!

The only occasions when I don't use strict mode is when 
I forget to write "use strict", which is most of the time.

Ideally, I would like to get rid of the pragma, while making strict mode the default for ES6. But it would be ES6 strict mode, which does not have to be the same as ES5 strict mode.

If there is anything in ES5 strict mode that cannot be implemented efficiently or that gives other reasons for not wanting to use strict mode, on purpose (rather than by accident/lack of knowledge), then ES6 strict mode could perhaps be refined to get rid of those stumbling blocks?

So, my question is: is it possible to merge the needs of ES5 sloppy mode users and the advantages of ES5 strict mode and come up with a one-mode-only ES6?

Claus

# Herby Vojčík (12 years ago)

Domenic Denicola wrote:

From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Brendan Eich Sent: Sunday, December 30, 2012 00:06

by yoking ES6 feature adoption to strict mode adoption, you multiply risks and reduce ES6 adoption.

I'd like to lend a little bit of defense to Kevin's ideas here. Namely, it seems easy to me to imagine the following:

  • "Oh cool, ES6 is in $MY_FAVORITE_JS_ENVIRONMENT!"
  • "Awesome lemme insert some arrow functions to clean up all these map and filter arguments"
  • "What's that, Mr. Compiler? You won't let me use arrow functions unless I put 'use strict' at the top of my file?"
  • "OK, whatever, that seems lame, but arrow functions are worth it."

This is of course predicated on the code in question not being affected by the breaking changes of strict mode, which is probably true of most code written by early adopters today.

To be clear, there's obviously a lot of subtle issues here, as Brendan has pointed out. I do find it somewhat unlikely though, that if strict mode was required for anything ES6-ish, people would give up their new toys rather than point a pragma at the top of their file.

Yes.

The old conforming sloppy code will work.

The new must be strict to use new things.

But the new things are valuable. Wanting 'use strict' (or module, or class) should not be an issue for people writing new code. Nor, imho, for people redesigning big bunches of old code. The only losers of this reform are people with old codebase wanting to clean it using better new constructs but their boss prohibits them using 'use strict'. And even for them, class is giving opportunity of incremental progress.

I would solve the little issue of "class can be of very little granularity when using class expressions" by using only standalone class definitions* as implicitly strict (and using class expression in sloppy code would just end up with "new features only in strict mode" error).

(Although, as I write that last sentence, I realize this isn't much different than suggested use version 6 :-/)

But it isn't. So in fact no additional mode. That's important. :-)

Herby

  • If there are "module expressions", disallowing them, too.
# Brendan Eich (12 years ago)

Andreas Rossberg wrote:

On 29 December 2012 22:06, Brendan Eich<brendan at mozilla.com> wrote:

Andreas Rossberg wrote:

ES6+ will stay much longer (at least that's what we are working for). Consequently, what should take precedence are the expectations and needs of future users of ES. Those who will come to ES6+ without knowing nor caring about the colorful history of its earlier versions. For them, having various features locally change the semantics of unrelated constructs Whoa.

Who ever proposed that? It seems a misunderstanding. No one is saying that, e.g., destructuring formal parameters, or a rest parameter, should flip the containing function into strict mode. Banning duplicate formals in no wise does that.

We are discussing it for classes right now, and it has been on the table for other features (such as arrows or generators) several times, if my memory serves me right.

Two separate things:

  1. All new syntax with code bodies makes strict-by-fiat code bodies.

  2. New parameter forms restrict duplicate parameters.

Neither entails "various features locally chang[ing] the semantics of unrelated constructs"-- unless by "local" you mean the new syntax's head and "unrelated" the new syntax's body!

# Brendan Eich (12 years ago)

Andreas Rossberg wrote:

There also is the sloppy-mode-arguments-object vs destructuring issue.

Thanks, I forgot that one. It's a good point, since one cannot statically catch all 'arguments' uses in general.

Years ago we implemented destructuring parameters in JS1.7-1.8, without restricting arguments usage:

js> function f({x,y}, z) { arguments[0] = 42; return [x, y, z] }

js> f({x:1,y:2}, 3) [1, 2, 3] js> function f({x,y}, z) { arguments[1] = 42; return [x, y, z] }

js> f({x:1,y:2}, 3) [1, 2, 42] js>

If bad old sloppy arguments objects are really important to preserve in functions that use destructuring, we can keep support.

# Axel Rauschmayer (12 years ago)

I agree. To me it comes down to cognitive load. A good way of measuring that is whether one can state a simple rule. For Andreas’ approach, it would be: “If you want the new stuff, turn on strict mode or wrap a module around it.”

  • Pro 1JS: You can use new stuff everywhere.
  • Contra 1JS: You can’t use all of the new stuff. There are tricky exceptions and rules.

Another thought: What will JavaScript code look like once 99% of browsers in use support ES6? Will we have a language with coherent semantics and a simple structure? That is: is there a way to drop some of the trickiness, long term? And which of the approaches gets us there?

# Axel Rauschmayer (12 years ago)

It would actually be nice to have that as a feature: If the variable name is _ then it can be used multiple times. It’s a nice, self-descriptive way of saying that you don’t care about a parameter value.

# Andreas Rossberg (12 years ago)

On 30 December 2012 11:58, Brendan Eich <brendan at mozilla.com> wrote:

Two separate things:

  1. All new syntax with code bodies makes strict-by-fiat code bodies.

  2. New parameter forms restrict duplicate parameters.

Neither entails "various features locally chang[ing] the semantics of unrelated constructs"-- unless by "local" you mean the new syntax's head and "unrelated" the new syntax's body!

I did. It boils down to: I have this construct used locally here. For how many different syntactic constructs do I have to look out for in the context to determine what it means?

# Herby Vojčík (12 years ago)

Axel Rauschmayer wrote:

It would actually be nice to have that as a feature: If the variable name is _ then it can be used multiple times. It’s a nice, self-descriptive way of saying that you don’t care about a parameter value.

It is a valid identifier, one may actually use it. Better allow having nothing in there to say "I ignore".

# Andreas Rossberg (12 years ago)

On 30 December 2012 12:50, Axel Rauschmayer <axel at rauschma.de> wrote:

It would actually be nice to have that as a feature: If the variable name is _ then it can be used multiple times. It’s a nice, self-descriptive way of saying that you don’t care about a parameter value.

That underscore wildcard is the exact syntax used in functional languages, and very useful, I agree. In JS, that syntax would be a breaking change, unfortunately. But we could use something else (e.g. I proposed '.' in the past).

# Mark S. Miller (12 years ago)

On Sun, Dec 30, 2012 at 3:39 AM, Axel Rauschmayer <axel at rauschma.de> wrote:

I agree. To me it comes down to cognitive load. A good way of measuring that is whether one can state a simple rule. For Andreas’ approach, it would be: “If you want the new stuff, turn on strict mode or wrap a module around it.”

+1. The expository benefit of this kind of simple rule is huge.

  • Pro 1JS: You can use new stuff everywhere.
  • Contra 1JS: You can’t use all of the new stuff. There are tricky exceptions and rules.

Here, Axel and Andreas repeat the mistake I made about the definition of 1JS. The above “If you want the new stuff, turn on strict mode or wrap a module around it.” rule is perfectly consistent with 1JS as Dave has clarified it (and as he originally stated it).

Another thought: What will JavaScript code look like once 99% of browsers in use support ES6? Will we have a language with coherent semantics and a simple structure? That is: is there a way to drop some of the trickiness, long term? And which of the approaches gets us there?

In the short term, while people are making the transition, the rule would be stated as above “If you want the new stuff, turn on strict mode or wrap a module around it.” Later, once ES6 is everywhere, it would instead be stated as "Turn on strict mode or code in a module in order to code in JavaScript. If you don't, you'll be coding instead in an insane JavaScript fossil that exists merely for compatibility with old ES3 code. No one even understands its scoping rules."

# Brandon Benvie (12 years ago)

On Sunday, December 30, 2012, Mark S. Miller wrote:

In the short term, while people are making the transition, the rule would be stated as above “If you want the new stuff, turn on strict mode or wrap a module around it.” Later, once ES6 is everywhere, it would instead be stated as "Turn on strict mode or code in a module in order to code in JavaScript. If you don't, you'll be coding instead in an insane JavaScript fossil that exists merely for compatibility with old ES3 code. No one even understands its scoping rules."

This is a very attractive idea. It seems like it is is the simplest of all possible stories to learn, teach, use, specify, and implement.

# Brendan Eich (12 years ago)

Axel Rauschmayer wrote:

I agree. To me it comes down to cognitive load. A good way of measuring that is whether one can state a simple rule. For Andreas’ approach, it would be: “If you want the new stuff, turn on strict mode or wrap a module around it.”

That is different from what TC39 has been working on, which Allen has been editing.

Making a simple statement is an easily gamed contest. Here's mine:

"If you want the new stuff, just use it."

I win :-|. Granted, some problems remain (more below)!

A couple of more serious comments:

We don't realize a better spec by pushing all new syntax into strict code, because the grammar doesn't know about modes. The grammar covers everything -- new syntax and old. So the semantics have to do "if strict, throw" on new syntax.

If we go down this road, we will crud up all the new semantics for new syntax with strict checks to throw early errors when the new syntax is used in sloppy code.

So the spec will be messier and the teaching slogan will be longer than it could be without the "turn on strict mode of wrap a module around it" part, if we go down this road. Perhaps it's the best path, but I am far from convinced.

  • Pro 1JS: You can use new stuff everywhere.
  • Contra 1JS: You can’t use all of the new stuff. There are tricky exceptions and rules.

Check me: I think the only exceptions that we have found are let and function-in-block. At the last TC39 meeting, we resolved to try reserving let contextually in sloppy code. Results not yet in on that front, so by the book, following our own process, we should get some more data.

Function-in-block is indeed a problem without evangelization. But Mark said he was game. I don't know how much Google, Microsoft, Apple, and Mozilla can do to evangelize f-i-b content owners (if any are still around and actively maintaining) to switch from non-ES6 to ES6 f-i-b semantics, but that is also something we could try.

If we get past these two, then we're in the winning "Pro 1JS" / "If you want the new stuff, just use it" scenario.

Another thought: What will JavaScript code look like once 99% of browsers in use support ES6? Will we have a language with coherent semantics and a simple structure? That is: is there a way to drop some of the trickiness, long term? And which of the approaches gets us there?

You're getting ahead of reality here. Consider that no static code mode can tame implicit conversions, which strict mode leaves intact apart from removing |this| wrapping of primitives. Implicit conversions happen on values that can flow anywhere, including references to objects in the heap. There's no static strict/sloppy partitioning.

Implicit conversions remain the biggest WTF source. To tame them I think we need to work on value objects and beyond. This is nowhere in sight for ES6.

# Brendan Eich (12 years ago)

Brandon Benvie wrote:

On Sunday, December 30, 2012, Mark S. Miller wrote:

In the short term, while people are making the transition, the rule
would be stated as above “If you want the new stuff, turn on strict
mode or wrap a module around it.” Later, once ES6 is everywhere, it
would instead be stated as "Turn on strict mode or code in a module in
order to code in JavaScript. If you don't, you'll be coding instead in
an insane JavaScript fossil that exists merely for compatibility with
old ES3 code. No one even understands its scoping rules."

This is a very attractive idea. It seems like it is is the simplest of all possible stories to learn, teach, use, specify, and implement.

Come on, you guys. Your own biases are on parade here.

First, the scoping rules of sloppy mode are know and used, some even advocate using them in full (yes, even 'with').

Strict mode does tame most of the scoping crazy, I like it. But it does not make

  • free variables an early error;

  • implicit conversions, e.g. random string to 0 or NaN, or anything that can wreck your == day, an early error;

  • fetching a missing property and getting undefined, which flows miles downstream before being dereferenced, any kind of prompt error that blames the missing property and its base object.

So exaggerating the "insane" sloppy mode's flaws both overdoes it in the face of lots of legacy and many developers who must deal with it (some of whom like it), and oversells strict mode as fixing the above bulleted items.

All this happy talk about teaching slogans smells like propaganda. It won't work. It is still overcomplicated and hard to use compared to "new syntax, just use it". And the exaggerations and overstatements will bite back, as badly as or worse than any 'let [x] = y' breaking change.

# Axel Rauschmayer (12 years ago)
  • Pro 1JS: You can use new stuff everywhere.
  • Contra 1JS: You can’t use all of the new stuff. There are tricky exceptions and rules.

Check me: I think the only exceptions that we have found are let and function-in-block. At the last TC39 meeting, we resolved to try reserving let contextually in sloppy code. Results not yet in on that front, so by the book, following our own process, we should get some more data.

Function-in-block is indeed a problem without evangelization. But Mark said he was game. I don't know how much Google, Microsoft, Apple, and Mozilla can do to evangelize f-i-b content owners (if any are still around and actively maintaining) to switch from non-ES6 to ES6 f-i-b semantics, but that is also something we could try.

If we get past these two, then we're in the winning "Pro 1JS" / "If you want the new stuff, just use it" scenario.

Thanks! Good points.

The slogan thing may be a bit simplistic, but I do think it matters, because it implies a clear strategy (not necessarily the other way around). And “If you want the new stuff, just use it [wherever – independently of the mode you are currently in]” sounds good to me. If there really are no exceptions to this rule then that is awesome.

Another thought: What will JavaScript code look like once 99% of browsers in use support ES6? Will we have a language with coherent semantics and a simple structure? That is: is there a way to drop some of the trickiness, long term? And which of the approaches gets us there?

You're getting ahead of reality here.

Absolutely. And my intention is not to fight reality (even if it sometimes might come across that way), but to get a general sense of a long-term direction. Often valid reasons stand in the way of some of the more idealistic visions, but I still think it helps to discuss them. At least it helps me understand what’s going on.

If 1JS works out, we’ll continue to have a random mix of strict and non-strict code, right? <idealism>

But then why not make it a long-term goal to eliminate the difference between strict and non-strict? What is the main impediment to that? Perhaps the different value of this in non-method functions. Checking the value of this is sometimes used to check whether a function has been invoked as a method or as a non-method function. So maybe it makes sense to introduce another way of enforcing a certain way of invocation. Everything else that is non-strict should disappear over time (right?).

Consider that no static code mode can tame implicit conversions, which strict mode leaves intact apart from removing |this| wrapping of primitives. Implicit conversions happen on values that can flow anywhere, including references to objects in the heap. There's no static strict/sloppy partitioning.

Implicit conversions remain the biggest WTF source. To tame them I think we need to work on value objects and beyond. This is nowhere in sight for ES6.

As it stands, ES6 is great (independently of 1JS or not), already. I made a list of the 10 biggest JS pitfalls and most of them will be gone under ES6. Much less to worry about, much easier to learn.

That doesn’t mean I’m not looking forward to value objects, though. ;-)

# Brendan Eich (12 years ago)

Axel Rauschmayer wrote:

I made a list of the 10 biggest JS pitfalls and most of them will be gone under ES6. Much less to worry about, much easier to learn.

Could you share your 10-biggest list?

# Claus Reinke (12 years ago)

It would actually be nice to have that as a feature: If the variable name is _ then it can be used multiple times. It’s a nice, self-descriptive way of saying that you don’t care about a parameter value.

That underscore wildcard is the exact syntax used in functional languages, and very useful, I agree. In JS, that syntax would be a breaking change, unfortunately. But we could use something else (e.g. I proposed '.' in the past).

Some languages even interpret any id with '_'-prefix as wildcard, and warn about uses as likely errors. Btw, the existing duplicate-parameter error feature smells of should-be-a-warning-not-an-error.

But '_' is in popular use in JS, there being few good short identifiers.

How about moving the early error from parameter list to parameter use? If a parameter isn't used, even if duplicated, it isn't likely to be an error (*), and this would allow for wildcard use. If a duplicate parameter is used at all, that seems to be the case to guard against.

Claus

(*) Though one can always construct a case where something is an error, eg: function(a,a) { return b } // meant a,b instead of a,a

# Claus Reinke (12 years ago)

Another thought: What will JavaScript code look like once 99% of browsers in use support ES6? Will we have a language with coherent semantics and a simple structure? That is: is there a way to drop some of the trickiness, long term? And which of the approaches gets us there?

In the short term, while people are making the transition, the rule would be stated as above “If you want the new stuff, turn on strict mode or wrap a module around it.” Later, once ES6 is everywhere, it would instead be stated as "Turn on strict mode or code in a module in order to code in JavaScript. If you don't, you'll be coding instead in an insane JavaScript fossil that exists merely for compatibility with old ES3 code. No one even understands its scoping rules."

I'd like to add one JS coder's view, and a suggestion (at the end).

Not long ago, the ES situation -to me- looked like this:

  • ES3 engines are dying

  • ES5 is about to be in-practice standard (a state now achieved?)

  • if you want to look ahead or catch more silly errors, use ES5 strict

  • because ES3 engines aren't quite dead, ES5 strict mode is a pragma that will be ignored by those engines

  • ES6 will start from ES5 strict mode

While complicated as status quo, there was a clear progression path: use ES5 now, move to ES5 strict when possible, in anticipation of ES6. In particular, it was clear that ES3 dependence or ES5 sloppy mode were temporary, with very short remaining intended life-time, and their problematic features, as far as addressed in ES5 strict mode, were on their way out for ES6 (such as 'with').

These days, 'with' and sloppy mode are still in ES6, and there is talk of supporting them and ES3-dependent code in combination with ES6-new-features, perhaps forever ("can't deprecate the web"), together with in-the-wild code that depends on non-ES features.

The quotes at the top of this message echo Andreas' argument (ES future is longer than ES past) against a state of discussion that gives high prominence to the past (support unmaintained code).

In other languages, I would suggest tooling as a remedy (automated code upgrade, as done for Cobol and the year 2000 issue), but for JS, that route seems impractical (analysis being undecidable, and owners of unmaintained JS code being greater in number and having smaller budgets than those of unmaintained Cobol code).

// suggestion

Perhaps there is a way to make the automated upgrade problem solvable/cheap? Instead of ES6+ supporting sloppy mode and strict mode and mixtures of new features with sloppy mode indefinetly, how about turning the situation on its head:

  • ES6 engines default to strict mode, with new features (the cleaner future)

  • ES6 engines support a "use ES5" pragma that switches off both new features and strict mode (give a helping hand to support old code)

  • ES6 engines ignore "use strict"

  • ES3/5 engines ignore "use ES5"

// end suggestion

That way, you don't have to version to use new language (the current standard), only to use old language. And all code owners have to do to support unmaintained code is to slap "use ES5" in front of it - easily automated.

ES engine implementers would have to support ES5 mode, but at least they wouldn't have to support mixtures of ES5 sloppy mode and ES6+ features. ES5 mode would treat ES6 features the way an ES5 engine would.

As an added bonus, future ES committees would have an easier time querying the web for code still relying on ES5. Perhaps some day, ES5 mode will no longer be needed, but meanwhile ES6+ won't be complicated by it.

Just a thought, Claus

# Brendan Eich (12 years ago)

Claus Reinke wrote:

// suggestion

Perhaps there is a way to make the automated upgrade problem solvable/cheap? Instead of ES6+ supporting sloppy mode and strict mode and mixtures of new features with sloppy mode indefinetly, how about turning the situation on its head:

  • ES6 engines default to strict mode, with new features (the cleaner future)

  • ES6 engines support a "use ES5" pragma that switches off both new features and strict mode (give a helping hand to support old code)

  • ES6 engines ignore "use strict"

  • ES3/5 engines ignore "use ES5"

// end suggestion

That way, you don't have to version to use new language (the current standard), only to use old language. And all code owners have to do to support unmaintained code is to slap "use ES5" in front of it - easily automated.

Sorry, this is deeply unrealistic.

Easily automated by whom? Who does all the non-automated work testing and deploying? Of unowned content hosted by companies paying the bill for the hosting but not for any maintenance or changes?

You're talking about the entire web, billions of pages at this point. Scripts are at least as common as pages going by MIME type requests:

www.phpied.com/digging-into-the-http-archive/?utm_medium=referral&utm_source=pulsenews

(look for "Most common mime types").

Your suggestion also doesn't work without perfect, up front conversion. Any laggard web content of size, and browser game theory kicks in. First browser to do as you propose "breaks (a sizeable part of) the web" for its users and loses market share.

The web used to be indexable in a coherent sample but its size outgrew that limit long ago. If search engines can't coherent index, there's no way we'll get "tooth-full" (that is, enforced by all browsers in a sea-change event) ES6-strict-only enforcement unless the script has "use ES5". We won't get "use ES5" where needed, and no browser vendor will take the chance.

A closing thought: you may want ES5 strict to be the basis of all future code, but it has not yet been widely adopted. It should be and may be, but time will tell. Best to work to increase the quantity of strict-mode code on the web over time.

That's why I keep advocating making all new ES6 syntax-forms with code bodies strict by fiat.

Andreas, Mark et al. want new syntax only under strict mode (implicitly in module, mostly -- I have to keep asking!). That works too, except for the overhead of opting into strict mode, which is easy to forget to do.

In no case does breaking the web (really, breaking any browser foolish enough to try) work.

# Kevin Smith (12 years ago)

This is a bit long - bear with me...

First, let me make one more argument as to why "new syntax, just use it" won't work:

(a) In ES6, "let" is the preferred way to declare variables. Let's not be relativistic to the point of goo here. Block-scoped variables are "better". As such, "let" is of central importance to the language. (b) ES6 sloppy mode cannot have "let". (c) Therefore, ES6 sloppy mode is a hobbled, incomplete version of the ES6 language, and (d) Since ES6 sloppy mode is not the same as ES6, there can be no "1JS" as long as ES6 sloppy mode exists.

Sure, you could attack (b) by using parsing tricks and special cases. You can make anything "work". But then we're shirking the language designer's responsibility of guarding the values of simplicity and elegance.

I take it that you agree in principle with strict mode. If I understand correctly, your central argument against "1JS under strict" is that:

(a) Strict mode is not popular. (b) If ES6 syntax is strict-only, then ES6 may well be unpopular.

So why is strict mode not popular? The answer is quite simple: there's no carrot. It limits the user (in good ways, of course) without providing any additional power to offset those limitations. ES6, built exclusively on top of strict mode, provides those missing carrots.

If that's the case, then why are some users vehemently anti-strict? As you've stated, javascript is a big tent with many loud voices inside. It doesn't matter how the language evolves, there are going to be users on soapboxes proclaiming that "standards bodies suck" or shouting other blustery provocations. Change always creates winners and losers. But the language must evolve nevertheless.

What would convince you that strict-mode would not present a problem for ES6 adoption, if ES6 syntax were strict-only?

# Brendan Eich (12 years ago)

Kevin Smith wrote:

This is a bit long - bear with me...

First, let me make one more argument as to why "new syntax, just use it" won't work:

(a) In ES6, "let" is the preferred way to declare variables. Let's not be relativistic to the point of goo here. Block-scoped variables are "better". As such, "let" is of central importance to the language. (b) ES6 sloppy mode cannot have "let".

That's overstated, and as such it contradicts the tenuous consensus of the last TC39 meeting: to reserve 'let' contextually in sloppy mode and evangelize any let [x] = y code out there already (which we've yet to find -- 'let' is used as an identifier, short for 'letter', but not indexed into on LHS).

The rest of your reasoning is therefore overstated. It does not follow if we can reserve 'let' in ES6, mode-free.

(c) Therefore, ES6 sloppy mode is a hobbled, incomplete version of the ES6 language, and

See above.

(d) Since ES6 sloppy mode is not the same as ES6, there can be no "1JS" as long as ES6 sloppy mode exists.

Here I want to refine my Platonic prettiness critique. You talk about ES6 as if it can be a thing, which has a timeless existence and truth and beauty. Kind of like a dodecahedron -- a pure "Math thing".

I see that, but it's an abstraction. It is not real, it is ideal. In reality, you might argue the spec approximates this thing, but there are many problems.

What I think "exists": ES6 as a practical language with a large user community who apprehend it in pieces, and sometimes using different metaphors or incomplete and even inconsistent "theories" or schools of thought. It's a human thing, not a Math thing.

In this light, "1JS" is totally winning. It's a "true myth" as much, or moreso in my view, as the "use strict and you'll lose the crazy" true-myth.

Sure, you could attack (b) by using parsing tricks and special cases.

We agreed at the last meeting to treat 'let' as a contextual keyword at start of statement if followed by an Identifier, '{' or '['. That is a special case, but so what? 'module' was not reserved in ES1-5 so it needs a special case too.

The spec must serve the users. Not the other way around. Or would you give up 'module' from sloppy mode?

You can make anything "work". But then we're shirking the language designer's responsibility of guarding the values of simplicity and elegance.

These matter a lot but they are rather less well-defined than you make out here. I think 1JS is simple and elegant, even with other new syntax than 'module' as its own opt-in. I think I can make that case, and I'm trying to.

But to continue my point above, the simplicity and elegance, subjective in many ways, of the "ideal" ES6 must take a back seat to the real ES6, including its ease of adoption. That's where I think requiring "use strict"; to use new syntax (other than 'module') hurts more than it helps.

Imagine you are adapting existing code, including popular libraries not yet in strict mode, to a new app targeting ES6 or better runtimes directly, and ES5 and older via a compiler such as matthewrobb/six. You are not yet be ready to "use strict" in the concatenation of all the code -- there's too much risk of breaking something, and never enough test coverage.

You want to use ES6 features such as rest parameters and destructuring right away, before any "use strict" or module wrapping. Under your proposal, you can't. You have to multiply risks and spend time turning on strict mode, testing harder in old and new and middling (IE9, anyone?) browsers.

Why is this a good thing?

Oh sure, in 10 years, no worries. But let's consider that future, which Andreas and others argue is larger than the past.

In 10 years, you want everyone to use modules, but there'll still be top-level code, rapid prototyping, and so on. For such programs, you want everyone to write the old

"use strict";

chestnut, about which StackOverflow misadvises now (and probably will then :-P) that minifiers can safely remove this "comment"?

Where's the ideal truth and beauty in this useless-string-expression-statement-as-pragma hack?

I take it that you agree in principle with strict mode. If I understand correctly, your central argument against "1JS under strict" is that:

(a) Strict mode is not popular.

No, I said it's not widely adopted and I've chosen my words carefully. Re-read my last few messages. It will take time to win everyone over, and even then the Law of Least Effort says it will be left out now and then, forever. Nothing on track for Harmony will insist on it as a shibboleth that must be uttered in some future, say ES8.

So it will be left out, and not every program is a module.

I really don't think I've been unclear about this. In particular I don't think I used popularity as some kind of static construct, ever. I've argued about slow (many years) adoption, which is an empirical fact. I've argued based on the design of the pseudo-pragma itself, that it tends to be left out. I've therefore argued against multiplying risks. That's it.

(b) If ES6 syntax is strict-only, then ES6 may well be unpopular.

Not quite. This is where I think a reductio ad absurdum has been put in my mouth. I never wrote that people will say "ES6, yay! Wait, I have to hassle with strict mode enabling?" and ES6 will suffer. That's too simple.

Yes, some people will bitch. They are probably mostly the same folks who will not want ES6 anyway, but a few would be open to what I propose: new syntax as its own opt-in (and with strict bodies, where there are code bodies). But let's leave them aside for a minute.

The problem I see is rather the permanent requirement for the "use strict"; shibboleth, and the ritual spanking one will get when forgetting to utter it up front before using any ES6 feature, however lovely and useful in a legacy or mixed codebase.

Again, why?

To preserve some idea based on your economics for simplicity and elegance but not mine? We could perhaps try to unify how we count these goods. But I think we should first try to get on the same real, as-used-in-practice, developer-facing terrain I'm arguing trumps whatever Platonic ideal we might (and probably do) share.

So why is strict mode not popular? The answer is quite simple: there's no carrot. It limits the user (in good ways, of course) without providing any additional power to offset those limitations. ES6, built exclusively on top of strict mode, provides those missing carrots.

There's no carrot and there are a few sticks, which are going away but not yet gone (performance faults, concatenation hazards, downrev browsers up to IE9 still in the field). Don't forget the sticks in the "short run".

But even in the longer run, with no sticks, ask yourself: "why am I requiring all users of new post-ES5 syntax, which could be a lot (future larger than past) to utter some silly string constant expression statement to use the new syntax, except for 'module', maybe?"

I see no simplicity and less elegance in making such a permanet requirement for "use strict".

If we want more strict code sooner, let's make all the new code-body-bearing syntax in ES6 strict by fiat.

If that's the case, then why are some users vehemently anti-strict?

Opinions vary on all sorts of things. Your argument here is off target. My argumet is not about popularity or fickle developers. It is about the cost of "use strict" in itself, and its risks gratuitously multiplying to reduce the odds of good ES6 adoption experience and long-run ES6, ES7, ES8, and (I hope not) ES9 truth and beauty.

In other words, I'm arguing about better design, both in terms of intrinsic expressiveness and in terms of human factors. I don't think "use strict" is expressive or usable in the large, or at least not any more so than 'module' wrapping or (my position) 'class' or other body form (generators, arrows) wrapping.

Pseudo-pragma vs. new syntax with strict-by-definition body -- this is a no-brainer for me. But I don't have a particular "use strict"; adoption axe to grind. I want more strict code, sooner, with less ugly boilerplate and potential for painful adoption.

As you've stated, javascript is a big tent with many loud voices inside. It doesn't matter how the language evolves, there are going to be users on soapboxes proclaiming that "standards bodies suck" or shouting other blustery provocations. Change always creates winners and losers. But the language must evolve nevertheless.

Nothing here is at issue, this is off target. Let's get back to the design issue.

What would convince you that strict-mode would not present a problem for ES6 adoption, if ES6 syntax were strict-only?

Obviously, if "use strict" were much more rapidly adopted, not necessarily majority by large-survey counts (github, web crawls) but trending up toward that end in a way that would be hard to reverse.

Other than that, you have to go back and actually engage my arguments. I do not have as an axiom that strict-mode opt-in via "use strict" is a good in itself. It is a means to an end. There are other means, apparently we even agree on one ('module' wrapping).

# Kevin Smith (12 years ago)

(b) ES6 sloppy mode cannot have "let".

That's overstated, and as such it contradicts the tenuous consensus of the last TC39 meeting: to reserve 'let' contextually in sloppy mode and evangelize any let [x] = y code out there already (which we've yet to find -- 'let' is used as an identifier, short for 'letter', but not indexed into on LHS).

The rest of your reasoning is therefore overstated. It does not follow if we can reserve 'let' in ES6, mode-free.

Yes, but see below...

Here I want to refine my Platonic prettiness critique. You talk about ES6

as if it can be a thing, which has a timeless existence and truth and beauty. Kind of like a dodecahedron -- a pure "Math thing".

It most certainly is ; )

What I think "exists": ES6 as a practical language with a large user community who apprehend it in pieces, and sometimes using different metaphors or incomplete and even inconsistent "theories" or schools of thought. It's a human thing, not a Math thing.

It should strive toward truth and beauty. It should approach Math-y-ness. The Math-y-ness is what allows us to cut through all of that human social BS. Anyway, enough of philosophy; more practical stuff below...

We agreed at the last meeting to treat 'let' as a contextual keyword at

start of statement if followed by an Identifier, '{' or '['. That is a special case, but so what? 'module' was not reserved in ES1-5 so it needs a special case too.

Sure, but as I argued when I read about that consensus, it creates a situation where "let" is a second-class identifier. Either it's an identifier, or it isn't. Any middle ground is, well, sloppy! Not Math-y. : )

The spec must serve the users. Not the other way around. Or would you give up 'module' from sloppy mode?

Personally, yes. Only modules loaded by the module loader are implicitly strict.

Imagine you are adapting existing code, including popular libraries not yet

in strict mode, to a new app targeting ES6 or better runtimes directly, and ES5 and older via a compiler such as **matthewrobb/sixmatthewrobb/six. You are not yet be ready to "use strict" in the concatenation of all the code -- there's too much risk of breaking something, and never enough test coverage.

You want to use ES6 features such as rest parameters and destructuring right away, before any "use strict" or module wrapping. Under your proposal, you can't. You have to multiply risks and spend time turning on strict mode, testing harder in old and new and middling (IE9, anyone?) browsers.

Sorry, I don't buy it.

If you have a legacy codebase, and you want to use some ES6 features without upgrading the whole thing to strict mode, then you can selectively upgrade the region that you are working on to strict mode by putting "use strict" inside of a function. If that's too loose-grained, then you shouldn't be fiddling with new features at all.

And if you're in a situation where you can't go strict, then you surely aren't ready to depend on transcompilation.

In 10 years, you want everyone to use modules, but there'll still be top-level code, rapid prototyping, and so on. For such programs, you want everyone to write the old

"use strict";

In 10 years loading code via script tags will be an abandoned practice, except for bootstrapping the module loader. Look, "use strict" is the price that we have to pay for supporting a legacy language, in a legacy loading context, into perpetuity. It's not going to be free. Should we rather pay that balance by creating sloppy modes for all future ES versions? Is this the long term vision, then?

ES3 < ES5 sloppy < ES6 sloppier < ES7 sloppiest
       < ES5 strict < ES6 strict < ES7 strict

What comes after ES7 sloppiest mode? To what extent does each new sloppy version have to drift from its strict counterpart? They cannot converge, so divergence is the only possibility.

In this light, the least price for legacy support is to require "use strict" in legacy contexts (e.g. script tags).

Pull off the band-aid, bite the bullet, etc. More harm is often done by taking the slow road. And ES6, with it's substantial syntax improvements, is the best opportunity we'll have for getting it over with.

OK - so why not make all new code-bearing bodies implicitly strict then? Won't that buy us more strict mode usage? Well, sure, but the price is added complexity. It sounds simple enough, but when we start digging into the details, little problems emerge (like "let"). It's already complex enough to support both strict and sloppy modes, why compound that complexity by extending the reach of sloppy mode?

I think that pretty much sums up the position, and the horse may be quite beaten at this point. What do you think?

# Brendan Eich (12 years ago)

Kevin Smith wrote:

    (b) ES6 sloppy mode cannot have "let".


That's overstated, and as such it contradicts the tenuous
consensus of the last TC39 meeting: to reserve 'let' contextually
in sloppy mode and evangelize any let [x] = y code out there
already (which we've yet to find -- 'let' is used as an
identifier, short for 'letter', but not indexed into on LHS).

The rest of your reasoning is therefore overstated. It does not
follow if we can reserve 'let' in ES6, mode-free.

Yes, but see below...

Ok!

Here I want to refine my Platonic prettiness critique. You talk
about ES6 as if it can be a thing, which has a timeless existence
and truth and beauty. Kind of like a dodecahedron -- a pure "Math
thing".

It most certainly is ; )

Good so far.

What I think "exists": ES6 as a practical language with a large
user community who apprehend it in pieces, and sometimes using
different metaphors or incomplete and even inconsistent "theories"
or schools of thought. It's a human thing, not a Math thing.

It should strive toward truth and beauty. It should approach Math-y-ness. The Math-y-ness is what allows us to cut through all of that human social BS. Anyway, enough of philosophy; more practical stuff below...

The philosophy matters. It's an old debate, Plato vs. Aristotle (remember Crock and me at TXJS 2011?). I'm a realist, and the problems I'm citing are not just "human social BS" -- they involve human factors, usability, stuff that is not social but individual and primal (like forgetting "use strict"; or [for me] forgetting to turn off the Christmas lights each night :-P).

We agreed at the last meeting to treat 'let' as a contextual
keyword at start of statement if followed by an Identifier, '{' or
'['. That is a special case, but so what? 'module' was not
reserved in ES1-5 so it needs a special case too.

Sure, but as I argued when I read about that consensus, it creates a situation where "let" is a second-class identifier. Either it's an identifier, or it isn't. Any middle ground is, well, sloppy! Not Math-y. : )

Here again we already do not have the ideal as a realistic option.

Consider that 'get' and 'set' are contextual in ES5, but without any backward compatibility issues, and based on syntax extensions from SpiderMonkey that other engines reverse engineered. My point is that ES3 could not future-proof by reserving such short words, and did not need to. No one can foresee all future final/winning best-syntax designs.

And again, ES5 failed to reserve 'module' in strict mode, and ES1-3 never reserved 'module', so ES6 must make 'module' only contextually reserved. We are already in "either it's an identifier, or it isn't" default. If we can do it for 'module', why not for 'let'?

Holding the line at 1 is easier than at 2, but is the line worth holding? For what ideal, given the 'module' exception?

The spec must serve the users. Not the other way around. Or would
you give up 'module' from sloppy mode?

Personally, yes. Only modules loaded by the module loader are implicitly strict.

Now I'm confused. What about module M {...} (inline body)? What does "the module loader" mean, the system loader?

Simplicity and elegance are already gone if we're unsure of the conditions for the first exception to the rule. There will be more exceptions over time, based on our concrete experience over the last 16 years of ECMA-262 -- I'm pretty sure!

Imagine you are adapting existing code, including popular
libraries not yet in strict mode, to a new app targeting ES6 or
better runtimes directly, and ES5 and older via a compiler such as
https://github.com/matthewrobb/six. You are not yet be ready to
"use strict" in the concatenation of all the code -- there's too
much risk of breaking something, and never enough test coverage.

You want to use ES6 features such as rest parameters and
destructuring right away, before any "use strict" or module
wrapping. Under your proposal, you can't. You have to multiply
risks and spend time turning on strict mode, testing harder in old
and new and middling (IE9, anyone?) browsers.

Sorry, I don't buy it.

If you have a legacy codebase, and you want to use some ES6 features without upgrading the whole thing to strict mode, then you can selectively upgrade the region that you are working on to strict mode by putting "use strict" inside of a function.

And checking whether the function uses |this| and some no caller uses a global reference as the callee expression, intentionally passing |this| bound to the global object. There are other potential gotchas.

If that's too loose-grained, then you shouldn't be fiddling with new features at all.

Says you! :-)

Functions are not all small and simple in real code. Sure, a quick check for arguments, eval, and |this| usage should be enough -- but now I'm not using the new ES6 syntax to solve the problem at hand, I'm off doing strict-mode conversion for Kevin.

What's more, this will litter functions under maintenace and ES6-incremental upgrade with "use strict", and then one will have to go back later and do more sweeping stoop-labor, picking up the redundant "use strict"; clutter and commoning it at a higher level via a module or a single "use strict" in an outer function or global code.

No one works for free. There has to be a motivation. You wrote of "carrots" and the ES6 features are indeed sweet. Your "use strict" fetish is still a stick, not a carrot. You're trying to get the horse (developer) to take a whack by feeding it carrots after. Sadistic! :-/

And if you're in a situation where you can't go strict, then you surely aren't ready to depend on transcompilation.

That's obviously not true. CoffeeScript does not generate strict code yet!

In 10 years, you want everyone to use modules, but there'll still
be top-level code, rapid prototyping, and so on. For such
programs, you want everyone to write the old

"use strict";

In 10 years loading code via script tags will be an abandoned practice, except for bootstrapping the module loader.

I will bet you real (beer) money you're wrong.

Look, "use strict" is the price that we have to pay for supporting a legacy language, in a legacy loading context, into perpetuity.

No, you assert this but it does not prove itself and it's not an axiom.

  • "use strict" was a way to shoe-horn pragma syntax into ES5 (originally ES3.1) under "no new syntax" as a restriction.

  • It bites back because old browsers see nothing, yet it makes runtime semantic changes in new browsers, but time will heal this wound.

  • It's an eyesore, which I think is a non-trivial objection.

  • It is easy to leave out and hard to find when checking whether code in the middle of a function nest is strict.

Yes, it's standard, but so what? Having one means toward an end (strict code) does not mean we can't have other, more usable means over time. And again we seem to agree about module making some module bodies (only the out of line ones? I disagree but at least we're talking!) strict by fiat.

It's not going to be free. Should we rather pay that balance by creating sloppy modes for all future ES versions? Is this the long term vision, then?

ES3 < ES5 sloppy < ES6 sloppier < ES7 sloppiest

< ES5 strict < ES6 strict < ES7 strict

I'm not sure to whom you are addressing this rhetorical question. ES6 cannot mandate strict mode everywhere, so of course the default is sloppy. I'm the guy banging the drum for maximal (all new body-forms) strictness. That's the best we can do, for reasons recently rehashed in my reply to Claus Reinke on don't-break-the-web.

What comes after ES7 sloppiest mode?

You're ginning up a fake argument here: no one is adding more implicit conversion nonsense (well, almost -- destructuring does an implicit ToObject on the RHS and Andreas Rossberg disagrees; I will post a separate thread on this, it's worth revisiting). No one is pushing new with-like forms. No one is arguing for more arguments object usage, let alone more aliasing a la arguments[0] and first-formal named x.

Since we cannot mandate strict mode, we'll always have some sloppiness. Many on TC39 hope to provide new and better vegetables and fruits to lead the horses away from the bad old forms, and module is certainly sweet. Why stop there?

Note also that "use strict" cannot be extended arbitrarily with incompatible further strictness that governs existing forms, or we'll have more broken content tested only in old or new browsers.

We want ES5 strict mode to stay the same, and ES6 by default to be non-strict. This means new syntax could implicitly opt into strictness (as I advocate where there are code bodies, i.e., functions), or developers could opt in by composing "use strict" or module with new syntax.

But nothing here says we add more slop.

To what extent does each new sloppy version have to drift from its strict counterpart? They cannot converge, so divergence is the only possibility.

No one is making new slop that a stricter ES6 strict must ban. If we were, you'd have a point.

(Forthcoming post on destructuring addresses the deeper issue Andreas raises: future-proofing for pattern matching, vs. being "consistent" with old slop.)

In this light, the least price for legacy support is to require "use strict" in legacy contexts (e.g. script tags).

You are asserting again. "least price" sounds measurable. If we count chars, or measure actual error rates forgetting to add "use strict", or quantify any other way, I'm confident that requiring "use strict"; is not the least-cost or lowest-price path.

New syntax bearing a code body can be strict, and 1JS starting with Dave's proposal (in full) has at least 'module' strict by fiat, for both inline and out of line bodies.

This is least-price in terms of reading and writing. You could argue it is higher cognitive load, since one must check for two things, a governing "use strict"; or a module ... { with closing } bracketing the code in question.

But again, "use strict" has worse usability and it's harder to find (no bracketing). In most editors one can set a mark, find the nearest preceding 'module', match the } for its opening {, and see by point vs. mark line number differences, coloring, or better visualizations that the code in question is bracketed.

If most modules are out of line, then it's even easier, and no ugly and easy-to-forget (or delete) "use strict"; at top is required.

I went through the inline-body module case because I think we will see inline bodies in the long run, a minority cohort for sure, but still useful. And I think the same delimiting/bracketing exercise should apply to classes at least (strict by default).

Granted, classes can be finer-grain and typically will be. Even moreso, generators and arrows. However, for new code strict should be the default, and usually it won't bite back. The biting has come when adding "use strict" at the "top" without carefully reviewing or rewriting all the code affected (and ignoring concatenation).

Pull off the band-aid, bite the bullet, etc. More harm is often done by taking the slow road. And ES6, with it's substantial syntax improvements, is the best opportunity we'll have for getting it over with.

This is all kind of circular. You assert "use strict" is least-price and then make it the only way to get more strict code.

If by "pull off the band-aid" you mean get more strict code in the future than in the past, faster (more and faster over any measurable adoption interval), then making bodies strict by fiat wins.

OK - so why not make all new code-bearing bodies implicitly strict then?

(Finally! :-P)

Won't that buy us more strict mode usage? Well, sure, but the price is added complexity.

Complexity is not a unitary evil. It exists in your proposal too, not just due to usability and aesthetic problems of "use strict", but also in the friction in favor of sloppy code you are creating (those users, the ones I set aside temporarily in my last message, who would use ES6 but can't yet turn on strict mode at a high level).

Is the big fat future, with lots of modules, classes, arrows, and some generators, really more complex on balance, if those forms are strict? I don't think so.

It sounds simple enough, but when we start digging into the details, little problems emerge (like "let").

No, you are mixing topics. 'let' is a problem for new syntax as its own opt-in (so was 'module' but we did the obvious contextual thing).

'let' is not a problem for new-bodies-are-strict-by-fiat.

Please keep these two issues separate.

It's already complex enough to support both strict and sloppy modes, why compound that complexity by extending the reach of sloppy mode?

I'm not, I'm extending strict by design into new bodies.

I think that pretty much sums up the position, and the horse may be quite beaten at this point. What do you think?

I think the two issues I argue should be kept separate (new bodies are strict vs. new syntax is its own opt-in) are connected in your mind by "complexity".

If we keep the ability to make 'let' new syntax be its own opt-in (which again, we think we can keep via some lookahead restrictions and left context, similar to what we do elsewhere in ES1-5 and ES6 for 'module'), then there's no problem. But you could be right and we'll end up makin 'let' available only in strict mode (enabled by whatever means we choose).

Function-in-block faces a rougher road, and looks likely to precede 'let' into strict-only status -- but Mark at least wants to evangelize, so we don't have two f-i-b semantics (only one of them specified). We knew it might not be possible to change f-i-b semantics in all modes to match ES6, in particular to scope the hoisted binding to the enclosing block. This may happen, looks likelier, but not a done deal either.

Your complexity argument is that by putting all new syntax (save 'module') under a required "use strict" (or out-of-line module?), developers don't have to face certain complexity. I argue, to the contrary, that they face as much or worse. They have to:

  • find the governing "use strict" for a given piece of code in a function nest;

  • worry about module inline-to-out-of-line refactoring breaking pre-strict code that was put in the inline module in a prior refactoring step;

  • keep using 'var' in code when in doubt about strictness, retarding 'let' adoption.

  • face old f-i-b code that has different semantics from new f-i-b, but this one can't be solved other than by the end of strictness, so it is not an argument for or against a particular means of enabling strict mode.

The last bullet is a hard case that won't go away in any scenario, in the worst case where we can't evangelize old content to new semantincs. Yet it doesn't crack your perfect dodecahedron vs. my different (and more usable) smooth-hand-fitted shape :-P. Why not?

# Brandon Benvie (12 years ago)

The only motivation for me is in attempting to get rid of there even being two modes. I don't really care if it was strict or not strict, just that there's only one of them. Obviously the horse left the barn for ES5 long ago, but the desire to collapse down to one mode in as much code as possible is still motivating. I saw bundling as many carrots in with strict mode as a way to leverage developers into the single mode JS utopia of the future. I appreciate the arguments about the negatives of forcing the pragma incantation though.

How about making ES6 features only available inside modules? I guess that's kind of a cop-out though, since you don't always need a module. I still yearn for that utopian JS future where there is no need for two modes.

# Brendan Eich (12 years ago)

Brandon Benvie wrote:

The only motivation for me is in attempting to get rid of there even being two modes. I don't really care if it was strict or not strict, just that there's only one of them. Obviously the horse left the barn for ES5 long ago, but the desire to collapse down to one mode in as much code as possible is still motivating.

Indeed, this is a shared goal, happy to have it solved somehow. We're just arguing about "better" before committing.

I saw bundling as many carrots in with strict mode as a way to leverage developers into the single mode JS utopia of the future. I appreciate the arguments about the negatives of forcing the pragma incantation though.

Thanks.

How about making ES6 features only available inside modules? I guess that's kind of a cop-out though, since you don't always need a module. I still yearn for that utopian JS future where there is no need for two modes.

Utopia means no-place.

If between some or all new body forms imputing strictness, and evangelizing/teaching "use strict" or better means of opting in, we get to a world akin to Perl 5 in its modern form (CPAN etc.), where strict code predominates, that's good enough for me.

# Domenic Denicola (12 years ago)

I had what I hope is an original thought on solving this. Bear with me.

In Brendan's world, how will people end up "accidentally" in sloppy mode? With classes and modules and maybe generators and more in strict mode, I see the biggest remaining contingent being <script>-loaded one-offs or "bootstrapping" application code. [1] (If anyone has a better way of describing this set, please jump in.)

What I realized is that today that is exactly the sort of code you wrap in an IIFE, i.e. (function () { }());. Of course those of us who are on the strict-train end up writing this as

(function () {
  "use strict";

  // actual code here
}());

i.e. this is our new boilerplate for <script> code [2].

Well, what if we resurrected the do expression idea [3], but with a strict twist? Then we could evangelize the use of

do {
  // actual code here
}

as the new <script> boilerplate. It's pretty easy to sell, even as a replacement for non-strict IIFEs. And it gets more people on the strict train. Between this and modules, people should end up in sloppy mode fairly rarely ([1] aside :-/).

Thoughts?

  1. Possibly Node.js modules, assuming at best a backward-compatibility layer and at worst the failure of ES6 modules in the Node.js world. This proposal sadly has no solutions for that.
  2. Microsoft has very awesomely made this the default for new JS files in Visual Studio 2012 :O
  3. strawman:do_expressions

From: es-discuss-bounces at mozilla.org [es-discuss-bounces at mozilla.org] on behalf of Brendan Eich [brendan at mozilla.com] Sent: Monday, December 31, 2012 16:38 To: Brandon Benvie Cc: Mark S. Miller; es-discuss at mozilla.org Subject: Re: excluding features from sloppy mode

Brandon Benvie wrote:

The only motivation for me is in attempting to get rid of there even being two modes. I don't really care if it was strict or not strict, just that there's only one of them. Obviously the horse left the barn for ES5 long ago, but the desire to collapse down to one mode in as much code as possible is still motivating.

Indeed, this is a shared goal, happy to have it solved somehow. We're just arguing about "better" before committing.

I saw bundling as many carrots in with strict mode as a way to leverage developers into the single mode JS utopia of the future. I appreciate the arguments about the negatives of forcing the pragma incantation though.

Thanks.

How about making ES6 features only available inside modules? I guess that's kind of a cop-out though, since you don't always need a module. I still yearn for that utopian JS future where there is no need for two modes.

Utopia means no-place.

If between some or all new body forms imputing strictness, and evangelizing/teaching "use strict" or better means of opting in, we get to a world akin to Perl 5 in its modern form (CPAN etc.), where strict code predominates, that's good enough for me.

/be


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

# Kevin Smith (12 years ago)

And again, ES5 failed to reserve 'module' in strict mode, and ES1-3 never reserved 'module', so ES6 must make 'module' only contextually reserved. We are already in "either it's an identifier, or it isn't" default. If we can do it for 'module', why not for 'let'?

Easy: "module" is still a first class identifier, but with your proposed contortions, "let" is not (under sloppy mode, of course).

Personally, yes. Only modules loaded by the module loader are implicitly

strict.

Now I'm confused. What about module M {...} (inline body)? What does "the module loader" mean, the system loader?

Inline modules only in strict mode, in accordance with the rule. Only out-of-line modules are implicitly strict.

Functions are not all small and simple in real code. Sure, a quick check

for arguments, eval, and |this| usage should be enough -- but now I'm not using the new ES6 syntax to solve the problem at hand, I'm off doing strict-mode conversion for Kevin.

Well, you should be! : )

What's more, this will litter functions under maintenace and ES6-incremental upgrade with "use strict", and then one will have to go back later and do more sweeping stoop-labor, picking up the redundant "use strict"; clutter and commoning it at a higher level via a module or a single "use strict" in an outer function or global code.

Um - find and replace, dude. : )

And if you're in a situation where you can't go strict, then you surely

aren't ready to depend on transcompilation.

That's obviously not true. CoffeeScript does not generate strict code yet!

I meant for legacy JS. CS is all "new code".

In 10 years loading code via script tags will be an abandoned practice,

except for bootstrapping the module loader.

I will bet you real (beer) money you're wrong.

Alright - I'll take you up on that. If in 2022 anyone is using script tags for anything more than bootstrapping a module loader, I'll buy you a New Year's Eve beer!

  • It's an eyesore, which I think is a non-trivial objection.

Yes, but it's not required in out-of-line modules. Which will predominate quickly in new code (my prediction, yes).

  • It is easy to leave out and hard to find when checking whether code in

the middle of a function nest is strict.

Yes, it is easy to leave out, at least until you want to use an ES6 feature. Then you get spanked : )

I'm going to stop there.

Brendan, I feel like I'm in a compromising mood this evening. I can't really tell whether it's because your arguments have merit or because of argument by sheer exhaustion (as a previous computational theory professor of mine once said)...

In any case, here's my compromise:

(1) No opt-in required for new syntax, except: (2) No breaking changes to sloppy mode, and (3) No grammar contortions (e.g. let) to support sloppy mode. And (4) All new syntax forms with code bodies are implicit strict.

This might seem like a complete giveaway of my previous position. However, if the above four rules are adhered to, ES6 sloppy mode will be an incomplete, incomprehensible jumble of features and modes. An insane language, to which the only sane response will be to hang it all and just go all-strict.

Mission f**cking accomplished.

; )

# Brendan Eich (12 years ago)

Kevin Smith wrote:

And again, ES5 failed to reserve 'module' in strict mode, and
ES1-3 never reserved 'module', so ES6 must make 'module' only
contextually reserved. We are already in "either it's an
identifier, or it isn't" default. If we can do it for 'module',
why not for 'let'?

Easy: "module" is still a first class identifier, but with your proposed contortions, "let" is not (under sloppy mode, of course).

No, that's not correct. We have sloppy-mode code using 'let' as an identifier (whatever "first class" means) today. We don't want to break it.

The only place 'let' is contextually reserved in the quasi-consensus from the last TC39 meeting is at the start of a statement, when followed by an identifier, '{', or '['.

Similarly, 'module' is used and usable as an identifier, but not in malformed syntax that ES6 proposes to define: 'module' [no LineTerminator here] ModuleName ... at the start of a statement.

    Personally, yes.  Only modules loaded by the module loader are
    implicitly strict.


Now I'm confused. What about module M {...} (inline body)? What
does "the module loader" mean, the system loader?

Inline modules only in strict mode, in accordance with the rule. Only out-of-line modules are implicitly strict.

Any use-case-based rationale?

Thanks for clarifying the primacy of "the rule". It was not clear, and it does not match what Dave proposed that Mark reconfirmed as "1JS". Although Dave left some wiggle room in his first post, I want to say that my attempts to make all new body-forms strict don't fit under the consensus "1JS" name and I'm not trying to usurp it. Your proposal should be called "2JS" since to get the new stuff, you have to "use strict".

I will bet you real (beer) money you're wrong.

Alright - I'll take you up on that. If in 2022 anyone is using script tags for anything more than bootstrapping a module loader, I'll buy you a New Year's Eve beer!

Deal.

* It's an eyesore, which I think is a non-trivial objection.

Yes, but it's not required in out-of-line modules. Which will predominate quickly in new code (my prediction, yes).

I don't think so in the browser. Concatentors will be required to minimize requests, which will make modules inline again.

* It is easy to leave out and hard to find when checking whether
code in the middle of a function nest is strict.

Yes, it is easy to leave out, at least until you want to use an ES6 feature. Then you get spanked : )

Yeah, that's the thing I find turns off people at the "social BS" level. The Strunk&White-ian prescriptivism rings false and the kids start sassing off the gray-hairs. Not good for the Shire :-P.

I'm going to stop there.

Brendan, I feel like I'm in a compromising mood this evening. I can't really tell whether it's because your arguments have merit or because of argument by sheer exhaustion (as a previous computational theory professor of mine once said)...

We can wait till next year :-P and re-check. I'm not trying to bully anyone, just be a vigorous advocate (but not devil's advocate).

In any case, here's my compromise:

(1) No opt-in required for new syntax, except: (2) No breaking changes to sloppy mode, and (3) No grammar contortions (e.g. let) to support sloppy mode. And (4) All new syntax forms with code bodies are implicit strict.

Wow, I like!

Still some friction for 'let' that will retard 'var' replacement but it's survivable in my muddy palantir.

This might seem like a complete giveaway of my previous position. However, if the above four rules are adhered to, ES6 sloppy mode will be an incomplete, incomprehensible jumble of features and modes. An insane language, to which the only sane response will be to hang it all and just go all-strict.

If you say so. I suggest sloppy mode will be less used with (4) strict bodies than in the case you formerly advocated, due to the friction caused by rounding up adoption cost to use-strict conversion of surrounding code body.

Mission f**cking accomplished.

Let's take a breather. I am not out to force anyone into a bitter concession.

# Kevin Smith (12 years ago)

The only place 'let' is contextually reserved in the quasi-consensus from the last TC39 meeting is at the start of a statement, when followed by an identifier, '{', or '['.

Right - which makes "let" a "second class identifier" (sorry, made-up-term), since it can't be used in "let[x] = y". I shed dodecahedron-shaped tears at the thought.

Inline modules only in strict mode, in accordance with the rule. Only

out-of-line modules are implicitly strict.

Any use-case-based rationale?

In the end, I don't see any reason to write new code that is not structured as a collection of out-of-line modules (module files). Who knows, I might be missing a valid use case for non-module scripts though...

* It's an eyesore, which I think is a non-trivial objection.

Yes, but it's not required in out-of-line modules. Which will predominate quickly in new code (my prediction, yes).

I don't think so in the browser. Concatentors will be required to minimize requests, which will make modules inline again.

Yes, but inline modules (actually pre-loaded module registrations) within a larger out-of-line module:

// implicit strict because we're in an out-of-line module here
module "a.js" { ... }
module "b.js" { ... }
export * from "b.js";

Yes, it is easy to leave out, at least until you want to use an ES6

feature. Then you get spanked : )

Yeah, that's the thing I find turns off people at the "social BS" level. The Strunk&White-ian prescriptivism rings false and the kids start sassing off the gray-hairs. Not good for the Shire :-P.

I think this is a valid point, actually.

Let's take a breather. I am not out to force anyone into a bitter concession.

Nah - all dry humor there. I have 4 small children so this is about as much fun as I'm allowed to have on a New Year's Eve.

The "compromise" is actually serious, though. To reuse the feces metaphor, it doesn't so much polish the turd, as set it right out on the sloppy-mode sidewalk. Won't be long before people start riding their ES6 bikes on the strict side of the street.

Happy New Year!

# Mark S. Miller (12 years ago)

On Mon, Dec 31, 2012 at 7:49 PM, Brendan Eich <brendan at mozilla.com> wrote:

Kevin Smith wrote:

And again, ES5 failed to reserve 'module' in strict mode, and
ES1-3 never reserved 'module', so ES6 must make 'module' only
contextually reserved. We are already in "either it's an
identifier, or it isn't" default. If we can do it for 'module',
why not for 'let'?

Easy: "module" is still a first class identifier, but with your proposed contortions, "let" is not (under sloppy mode, of course).

No, that's not correct. We have sloppy-mode code using 'let' as an identifier (whatever "first class" means) today. We don't want to break it.

The only place 'let' is contextually reserved in the quasi-consensus from the last TC39 meeting is at the start of a statement, when followed by an identifier, '{', or '['.

Similarly, 'module' is used and usable as an identifier, but not in malformed syntax that ES6 proposes to define: 'module' [no LineTerminator here] ModuleName ... at the start of a statement.

    Personally, yes.  Only modules loaded by the module loader are
    implicitly strict.


Now I'm confused. What about module M {...} (inline body)? What
does "the module loader" mean, the system loader?

Inline modules only in strict mode, in accordance with the rule. Only out-of-line modules are implicitly strict.

Any use-case-based rationale?

Thanks for clarifying the primacy of "the rule". It was not clear, and it does not match what Dave proposed that Mark reconfirmed as "1JS". Although Dave left some wiggle room in his first post, I want to say that my attempts to make all new body-forms strict don't fit under the consensus "1JS" name and I'm not trying to usurp it. Your proposal should be called "2JS" since to get the new stuff, you have to "use strict".

In that case, I did not understand Dave's clarification. I thought Dave clarified this to mean only no new additional modes or opt-ins beyond those we already have, i.e., no mime types, additional pragmas, etc. As I understood Dave's clarification, 1JS is orthogonal to our decisions about how many of the new features to make available in sloppy mode. Andreas' position (and Kevin's pre-compromise position) is then consistent with 1JS.

Instead, what you say above seems to agree with what I thought 1JS meant when I posted my inflammatory message. If this is what 1JS means, then, again, I do not subscribe to 1JS.

If we cannot come to a common understanding of what 1JS means, we should find other terminology.

# Brendan Eich (12 years ago)

Kevin Smith wrote:

The only place 'let' is contextually reserved in the
quasi-consensus from the last TC39 meeting is at the start of a
statement, when followed by an identifier, '{', or '['.

Right - which makes "let" a "second class identifier" (sorry, made-up-term), since it can't be used in "let[x] = y". I shed dodecahedron-shaped tears at the thought.

Yes, you're right -- no such backward compatibility problem for 'module'. I'm with ya.

        * It's an eyesore, which I think is a non-trivial objection.

    Yes, but it's not required in out-of-line modules.  Which will
    predominate quickly in new code (my prediction, yes).


I don't think so in the browser. Concatentors will be required to
minimize requests, which will make modules inline again.

Yes, but inline modules (actually pre-loaded module registrations) within a larger out-of-line module:

// implicit strict because we're in an out-of-line module here
module "a.js" { ... }
module "b.js" { ... }
export * from "b.js";

Or a larger script tag!

That will need "use strict" or else.

    Yes, it is easy to leave out, at least until you want to use
    an ES6 feature.  Then you get spanked : )


Yeah, that's the thing I find turns off people at the "social BS"
level. The Strunk&White-ian prescriptivism rings false and the
kids start sassing off the gray-hairs. Not good for the Shire :-P.

I think this is a valid point, actually.

Thanks, it is a delicate one (I'm a prescriptivist about crucial matters, in English as in JS -- one must choose one's battles, though).

Let's take a breather. I am not out to force anyone into a bitter
concession.

Nah - all dry humor there. I have 4 small children so this is about as much fun as I'm allowed to have on a New Year's Eve.

LOL, I have you beat (5).

The "compromise" is actually serious, though. To reuse the feces metaphor, it doesn't so much polish the turd, as set it right out on the sloppy-mode sidewalk. Won't be long before people start riding their ES6 bikes on the strict side of the street.

Everyone wins :-).

Happy New Year!

Backatcha!

# Brendan Eich (12 years ago)

Mark S. Miller wrote:

Thanks for clarifying the primacy of "the rule". It was not clear, and it

does not match what Dave proposed that Mark reconfirmed as "1JS". Although Dave left some wiggle room in his first post, I want to say that my attempts to make all new body-forms strict don't fit under the consensus "1JS" name and I'm not trying to usurp it. Your proposal should be called "2JS" since to get the new stuff, you have to "use strict".

In that case, I did not understand Dave's clarification. I thought Dave clarified this to mean only no new additional modes or opt-ins beyond those we already have, i.e., no mime types, additional pragmas, etc.

Yes, that much -- but more.

As I understood Dave's clarification, 1JS is orthogonal to our decisions about how many of the new features to make available in sloppy mode.

No, Dave explicitly proposed that module be available in sloppy mode:

esdiscuss/2011-December/019112

"We can do better, and the way we can do it is with modules. We can introduce module syntax in a backwards-compatible way, and use them as the implicit opt-in for any new semantics [2]."

Andreas' position (and Kevin's pre-compromise position) is then consistent with 1JS.

It may be that we can relax "1JS" to mean less than Dave proposed, but I don't agree if it means "use strict" must be written to use any new syntax. Not that I'm playing brinksmanship games, just saying. Dave proposed it, the "1JS" name was coined soon after, and module in sloppy mode was always part of it.

Kevin separated module back out in his pre-compromise position but did not try to use or abuse "1JS" for that position.

I'm pretty happy with Kevin's compromise. Here it is again:

(1) No opt-in required for new syntax, except: (2) No breaking changes to sloppy mode, and (3) No grammar contortions (e.g. let) to support sloppy mode. And (4) All new syntax forms with code bodies are implicit strict.

What do you say?

Instead, what you say above seems to agree with what I thought 1JS meant when I posted my inflammatory message.

I don't know what you thought, but Dave always included module. You seemed to be reacting to 'let' contortions followed by function-in-block having two semantics, one de-facto and a browser-specific mess, the other block-scoped (hoisted binding and initialization of binding). The two are not the same!

If you stick with what Dave proposed, do you really object once again?

If this is what 1JS means, then, again, I do not subscribe to 1JS.

I don't know what "this" you mean. Can you be specific?

If we cannot come to a common understanding of what 1JS means, we should find other terminology.

We have an archive, I keep posting links. True, not every message is unambiguous, correct, and otherwise complete. But "1JS" as module-in-sloppy-mode-opts-into-ES6(-and-into-strict) was the original post (plus some followup on the -and-into-strict bit).

Again I explicitly do not call my "new bodies are strict by fiat" / "new syntax is its own opt-in (where we can get away with it without breaking the web)" combo "1JS". I'd like it to be ES6, though :-P. Perhaps we should focus on the substantial points and not worry about the "1JS" brand just yet.

# Brendan Eich (12 years ago)

Domenic Denicola wrote:

What I realized is thattoday that is exactly the sort of code you wrap in an IIFE, i.e. (function () { }());.

Script concatenation does not wrap an IIFE around the whole concatenation, and cannot in general.

# Mark Miller (12 years ago)

On Mon, Dec 31, 2012 at 9:12 PM, Brendan Eich <brendan at mozilla.commail.google.com/mail/?view=cm&fs=1&tf=1&[email protected]

wrote:

Mark S. Miller wrote:

Thanks for clarifying the primacy of "the rule". It was not clear, and it

does not match what Dave proposed that Mark reconfirmed as "1JS". Although Dave left some wiggle room in his first post, I want to say that my attempts to make all new body-forms strict don't fit under the consensus "1JS" name and I'm not trying to usurp it. Your proposal should be called "2JS" since to get the new stuff, you have to "use strict".

In that case, I did not understand Dave's clarification. I thought Dave clarified this to mean only no new additional modes or opt-ins beyond those we already have, i.e., no mime types, additional pragmas, etc.

Yes, that much -- but more.

As I understood Dave's clarification, 1JS is orthogonal to our

decisions about how many of the new features to make available in sloppy mode.

No, Dave explicitly proposed that module be available in sloppy mode:

mail.mozilla.orgpipermail/es-discuss/2011- December/019112.htmlesdiscuss/2011-December/019112

"We can do better, and the way we can do it is with modules. We can introduce module syntax in a backwards-compatible way, and use them as the implicit opt-in for any new semantics [2]."

Sorry, I have only been skimming this thread and didn't realize that Kevin had dropped "module". Yes, without even "module" being an implicit strict opt-in, we have a different beast, and one that I don't like.

Andreas' position (and Kevin's pre-compromise position)

is then consistent with 1JS.

It may be that we can relax "1JS" to mean less than Dave proposed, but I don't agree if it means "use strict" must be written to use any new syntax. Not that I'm playing brinksmanship games, just saying. Dave proposed it, the "1JS" name was coined soon after, and module in sloppy mode was always part of it.

Kevin separated module back out in his pre-compromise position but did not try to use or abuse "1JS" for that position.

I'm pretty happy with Kevin's compromise. Here it is again:

(1) No opt-in required for new syntax, except: (2) No breaking changes to sloppy mode, and (3) No grammar contortions (e.g. let) to support sloppy mode. And (4) All new syntax forms with code bodies are implicit strict.

What do you say?

My preference order:

1.a) To the extent clean and practical, new features are available only in strict mode, 1.b) Lexical f-i-b is available in sloppy mode as it is in ES6 strict, since no browser will prohibit f-i-b syntax in sloppy mode. Better to have the f-i-b sloppy semantics be aligned with the ES6 f-i-b strict semantics. 1.c) modules (both inline and out) implicitly opt-in to strict mode. 1.d) classes implicitly opt-in to strict mode. 1.e) nothing else causes an implicit strict mode opt-in.

  1. Like #1 but without #1.d (which I think of as Andreas' position)

  2. Like #1, but #1.e is replaced with 3.e) All code bodies within new function syntax is implicitly strict.

  3. Like #3, but #1.a is replaced with 4.a) To the extent clean and practical, new features are available in sloppy mode. I take it this is essentially your position and Kevin's compromise position?

  4. Where things stood at the end of the last TC39 meeting, where we were violating the "clean" of #4.a to kludge things like "let", non-duplicated-formals-sometimes, no-arguments-sometimes, weird scoping for default argument expressions, etc, into sloppy mode.

  5. Like #2 but without #1.c. Is this essentially Kevin's pre-compromise position?

Instead, what you say above seems to agree with what I thought 1JS

meant when I posted my inflammatory message.

I don't know what you thought, but Dave always included module. You seemed to be reacting to 'let' contortions followed by function-in-block having two semantics, one de-facto and a browser-specific mess, the other block-scoped (hoisted binding and initialization of binding). The two are not the same!

If you stick with what Dave proposed, do you really object once again?

If this is what 1JS

means, then, again, I do not subscribe to 1JS.

I don't know what "this" you mean. Can you be specific?

No longer relevant.

If we cannot come to a common understanding of what 1JS means, we

should find other terminology.

We have an archive, I keep posting links. True, not every message is unambiguous, correct, and otherwise complete. But "1JS" as module-in-sloppy-mode-opts-**into-ES6(-and-into-strict) was the original post (plus some followup on the -and-into-strict bit).

Again I explicitly do not call my "new bodies are strict by fiat" / "new syntax is its own opt-in (where we can get away with it without breaking the web)" combo "1JS". I'd like it to be ES6, though :-P. Perhaps we should focus on the substantial points and not worry about the "1JS" brand just yet.

yes. Good new year's resolution!

# Brendan Eich (12 years ago)

Mark Miller wrote:

On Mon, Dec 31, 2012 at 9:12 PM, Brendan Eich <brendan at mozilla.com, mail.google.com/mail/?view=cm&fs=1&tf=1&[email protected]> wrote:

Mark S. Miller wrote:

      As I understood Dave's clarification, 1JS is orthogonal to our
    decisions about how many of the new features to make available in
    sloppy mode.


No, Dave explicitly proposed that module be available in sloppy mode:

https://mail.mozilla.org/pipermail/es-discuss/2011-December/019112.html

"We can do better, and the way we can do it is with modules. We
can introduce module syntax in a backwards-compatible way, and use
them as the implicit opt-in for any new semantics [2]."

Sorry, I have only been skimming this thread and didn't realize that Kevin had dropped "module". Yes, without even "module" being an implicit strict opt-in, we have a different beast, and one that I don't like.

Cool, good to get back to Dave's o.p.

I'm pretty happy with Kevin's compromise. Here it is again:

(1) No opt-in required for new syntax, except:
(2) No breaking changes to sloppy mode, and
(3) No grammar contortions (e.g. let) to support sloppy mode.  And
(4) All new syntax forms with code bodies are implicit strict.

What do you say?

My preference order:

1.a) To the extent clean and practical, new features are available only in strict mode,

Just checking: is this because you want to promote "use strict"; usage?

1.b) Lexical f-i-b is available in sloppy mode as it is in ES6 strict, since no browser will prohibit f-i-b syntax in sloppy mode. Better to have the f-i-b sloppy semantics be aligned with the ES6 f-i-b strict semantics.

Agreed, and this requires evangelization. We need an action plan.

1.c) modules (both inline and out) implicitly opt-in to strict mode.

Note Kevin had inline modules legal as new syntax only under strict mode (via "use strict"; above in same unit, or else via next case), while out-of-line module bodies would be strict by definition.

1.d) classes implicitly opt-in to strict mode. 1.e) nothing else causes an implicit strict mode opt-in.

  1. Like #1 but without #1.d (which I think of as Andreas' position)

Sounds right, but let's let Andreas fend for himself :-P.

  1. Like #1, but #1.e is replaced with 3.e) All code bodies within new function syntax is implicitly strict.

  2. Like #3, but #1.a is replaced with 4.a) To the extent clean and practical, new features are available in sloppy mode. I take it this is essentially your position and Kevin's compromise position?

Yes, I think so, provided "clean and practical" means no 'let' in sloppy mode, per Kevin's item (3).

  1. Where things stood at the end of the last TC39 meeting, where we were violating the "clean" of #4.a to kludge things like "let", non-duplicated-formals-sometimes, no-arguments-sometimes, weird scoping for default argument expressions, etc, into sloppy mode.

Good to call this item (5) out. It needs more discussion. Whatever micro-modes mean, if we make new syntax in sloppy mode affect semantics of surrounding code, e.g., of the whole parameter list due to just one formal using destructuring, then we indeed have a difference from your 1-4 including sub-items.

I still think such non-local effects could be worth it, but they are a separate item from the others, especially your (4.a), the grand K-B compromise ;-).

  1. Like #2 but without #1.c. Is this essentially Kevin's pre-compromise position?

Not quite, as noted above Kevin really meant "no new syntax outside of strict code", so an inline module would have to nest directly in a "use strict";-governed code body, or else nested directly in an out-of-line module body. I.e., only out-of-line module bodies were implicityin (not opted into, nothing optional about it :-P) strict mode.

Thanks for the detailed order of preferences. Could you say a bit more about your rationale for this order?

# Brian Terlson (12 years ago)

I was already looking into something similar so I checked my dataset of scripts from 2235 sites and found only one example of duplicate identifier names: vnexpress.net. Here's the decl

function GetTopicHTML(sId,sTitle,sDate,sPath,sType,sPath,arItem,vType1,vType2,vCustomTitle,vShowHeader){

Notice sPath is duplicated. However, sPath is subsequently never used at all, so I'm not sure what the intent was here. Possibly just a bug or cruft.

That said, _ is being used to ignore parameters

# Brendan Eich (12 years ago)

This is good evidence to have, thanks.

It still doesn't mean that, for any such content whose owner decides to change a parameter to use destructuring, we can't link a ban on duplicate formals with that destructuring opt-in-by-its-own-new-syntax in ES6 sloppy mode. It's nowhere near enough duplicate formal usage to give me pause, at any rate.

Anyone maintaining these functions might rather find out about unintended duplicates!

# Nathan Wall (12 years ago)

Brendan Eich wrote:

Ease of teaching != successfully imparted knowledge at scale. Sorry, but it's true. People don't use "use strict"; at top level enough, and teaching them all will take time. Even then, because of the Law of Least Effort, it'll be left out.

This is the major objection some of us keep raising, and you don't engage with it. Please do!

This got me thinking (and I wonder if anyone has some data/experiences/guesses about this): How many people put <!doctype html> at the top of their HTML files in order to opt-in to standards mode.  I sure do!  Every time I write an HTML file it's the first thing I write. I wonder if that experience is the more common one?

I admit to not writing "use strict"; in most of my JS files due to laziness (I prefer to use strict when I'm taking my time). I guess the carrot isn't as big in ES5 as it is in HTML/DOM, at least in my eyes. It seems like a pretty parallel situation to me.

But with a bigger carrot, I sure wouldn't be too lazy!  And my assumption is others would gain the energy as well (unless there are still a bunch of devs out there not putting a doctype in their HTML, in which case the fear of Law of Least Effort is quite valid).

Does anyone have some data to quench my curiosity?

Nathan

# Andreas Rossberg (12 years ago)

On 1 January 2013 07:09, Mark Miller <erights at gmail.com> wrote:

On Mon, Dec 31, 2012 at 9:12 PM, Brendan Eich <brendan at mozilla.com> wrote:

Mark S. Miller wrote: I'm pretty happy with Kevin's compromise. Here it is again:

(1) No opt-in required for new syntax, except: (2) No breaking changes to sloppy mode, and (3) No grammar contortions (e.g. let) to support sloppy mode. And (4) All new syntax forms with code bodies are implicit strict.

What do you say?

My preference order:

1.a) To the extent clean and practical, new features are available only in strict mode, 1.b) Lexical f-i-b is available in sloppy mode as it is in ES6 strict, since no browser will prohibit f-i-b syntax in sloppy mode. Better to have the f-i-b sloppy semantics be aligned with the ES6 f-i-b strict semantics. 1.c) modules (both inline and out) implicitly opt-in to strict mode. 1.d) classes implicitly opt-in to strict mode. 1.e) nothing else causes an implicit strict mode opt-in.

  1. Like #1 but without #1.d (which I think of as Andreas' position)

Yes, although I'd even consider removing 1.c inline (matching your option 6 below).

But what do you mean by "to the extent clean and practical"? In my humble opinion, only two options are really acceptable at all: either all ES6 features work only in strict mode (my preference), or all ES6 features work in both modes (how I interpret 1JS). Something in-between, i.e., deciding inclusion into sloppy mode on a by-feature basis, is a non-starter in terms of usability and observable complexity. That is, rather (5) than (4) below.

  1. Like #1, but #1.e is replaced with 3.e) All code bodies within new function syntax is implicitly strict.

I'd be strongly opposed to this (and Kevin's point (4) in general).

# Brandon Benvie (12 years ago)

Without using modules as the indicator, how do you know whether code is intended to be run as ES6 or not? Do let and const count as ES6 (retroactively applying to code using the old non-standard versions, which are still currently supported by V8 and Spidermonkey)? Does it apply to code that appears to use Map, WeakMap, and Set (though the code might well refer to shimmed versions of these and not otherwise expect to run as strict)?

While there are many things that will absolutely indicate intention to run as ES6, there's a number of examples of ambiguity that make me doubt how successful an absolute judgment can be. This is why I think giving modules a double use as implicit opt-in/pragma has merit.

# Kevin Smith (12 years ago)

FWIW, after considering it for some time (there's a draft sitting around somewhere that I half-finished), I realize that point 4 ("All new syntax forms with code bodies are implicit strict") isn't going to work in seriousness. Why? Because if you list out the new syntactic forms with code bodies (object methods, generators, arrows, classes, and modules), it's really hard to make a case for implicit strict in anything but modules and classes. Too much refactoring hazard.

I like (#6), and it would effectively kill sloppy mode (win!), but it would require equipping the parser with a "strict-mode-spank-belt", which is probably not the best way to engender the trust and goodwill of the masses.

# Oliver Hunt (12 years ago)

let can't be used as an opt in (unfortunately :-( ) as it turns out let is used as a variable name in real world code.

Gavin and I briefly toyed with the concept of having let be a contextually identified, but that's not doable if you have destructuring assignment in sloppy mode.

My feeling is that destructuring assignment in sloppy mode is more of a win than let, although i'm not sure how others feel.

Note that this isn't a "opt-in", this is an attempt to try and minimise the differences between strict and sloppy modes. My ideal is that anything that can be unambiguously supported in sloppy mode should be.

# Brandon Benvie (12 years ago)

The incompatibilities between let/const as implemented in V8 and Spidermonkey and how they're specified in ES6 are an additional factor:

  • Per iteration loop binding (V8 and Spidermonkey don't do this for let/const).
  • TDZ. x; const x = 10 works in V8 and Spidermonkey currently, specified to throw ReferenceError in ES6

I think there's other differences.

# Brendan Eich (12 years ago)

Oliver Hunt wrote:

Note that this isn't a "opt-in", this is an attempt to try and minimise the differences between strict and sloppy modes. My ideal is that anything that can be unambiguously supported in sloppy mode should be.

I'm still with you on this.

# Brendan Eich (12 years ago)

There's no const in IE, so we are pretty sure we can take the hit of breaking "Mozilla" (non-IE branches, also WebKit, maybe Opera) code that uses const.

# Oliver Hunt (12 years ago)

On Jan 16, 2013, at 11:26 AM, Brandon Benvie <brandon at brandonbenvie.com> wrote:

The incompatibilities between let/const as implemented in V8 and Spidermonkey and how they're specified in ES6 are an additional factor:

  • Per iteration loop binding (V8 and Spidermonkey don't do this for let/const).

let isn't really relevant in sloppy mode, unless we decide to take let over destructuring (which would make me really sad)

  • TDZ. x; const x = 10 works in V8 and Spidermonkey currently, specified to throw ReferenceError in ES6

I'm not sure adding TDZ to sloppy mode is feasible for const. OTOH const is such a clusterfoo in sloppy mode i'm not sure what the compatibility story is -- I haven't looked at the different behaviours sufficiently to see if they can be merged. I suspect that they can be as const doesn't suffer quite as badly as block scoped functions.

Off the top of my head:

  • JSC will rebind a const if it's in a const declaration, eg. const x = 5; log(x)/5/; const x = 6;log(x)/6/; x = 7; log(x)/6/;
  • Opera in the past used const as an alias to var, i don't know their current behaviour

I don't know which version of IE picked up const (i'm assuming 10 has it?) and i'm not sure what V8/SM do.

# Brendan Eich (12 years ago)

Oliver Hunt wrote:

let isn't really relevant in sloppy mode, unless we decide to take let over destructuring (which would make me really sad)

You missed the last TC39 meeting, where we agreed (with some misgivings) to have both, but to break backward compat if any extant code indexes into let:

var let = str[i]; // let for letter let[x] = y; // hmm, indexing into a letter?

where x could be 0 or 'contains' (and y a replacement function, a forward polyfill or some such).

The last line above would be destructuring assignment, in sloppy mode ES6, per our last f2f meeting. Incompatible but we doubted any real code looked like that.

# Oliver Hunt (12 years ago)

Even 10? If that's the case anything using const is inherently tied to jsc,v8,moz,opera behaviour.

Presumably the strictest of those works, but maybe i'm wrong?

We should probably just enumerate all the differences and see which can be coalesced and which make "sense" in sloppy mode.

Obvious cases i can think of:

-- const x;

var x; const x; x = 5;

const x; var x; x = 5;

const x =4; var x = 5; log(x)

if (..) const x = .... else const x = ....

That's it for now. Maybe block scoping const will work in sloppy mode? is for (const x = ...) valid?

# Domenic Denicola (12 years ago)

Coincidentally, I compiled a list of interesting cases a few days ago, for both const and let. They were meant to be used in kangax's ES6 compatibility table:

kangax/es5-compat-table#58

In short:

const x; // SyntaxError let x; let x; // SyntaxError const x = 5; const x = 5; // SyntaxError x; const x = 5; // ReferenceError x; let x; // ReferenceError const x = 2; { x; const x = 5; } // ReferenceError let x; { x; let x; } // ReferenceError

plus a test of fresh per-loop iteration for let

Corrections welcome, and kudos to Brandon Benvie on pointing me to the fact that those last four should be ReferenceErrors.

# Oliver Hunt (12 years ago)

On Jan 16, 2013, at 11:54 AM, Domenic Denicola <domenic at domenicdenicola.com> wrote:

Coincidentally, I compiled a list of interesting cases a few days ago, for both const and let. They were meant to be used in kangax's ES6 compatibility table:

kangax/es5-compat-table#58

In short:

const x; // SyntaxError let x; let x; // SyntaxError const x = 5; const x = 5; // SyntaxError x; const x = 5; // ReferenceError x; let x; // ReferenceError const x = 2; { x; const x = 5; } // ReferenceError let x; { x; let x; } // ReferenceError

plus a test of fresh per-loop iteration for let

Corrections welcome, and kudos to Brandon Benvie on pointing me to the fact that those last four should be ReferenceErrors.

I'm not too interested in what the spec says these should/should not be. I'm interested in what shipping browser engines do. Presumably IE throws on all of them, but we need a nice table for const which is "supported" by multiple engines to show the differences in behaviour so that we can determine the best intersection.

# Brendan Eich (12 years ago)

Oliver Hunt wrote:

Even 10? If that's the case anything using const is inherently tied to jsc,v8,moz,opera behaviour.

Yes, even IE10.

Presumably the strictest of those works, but maybe i'm wrong?

Opera equates const and var, last I heard.

# Andreas Rossberg (12 years ago)

On 16 January 2013 19:33, Brandon Benvie <brandon at brandonbenvie.com> wrote:

Without using modules as the indicator, how do you know whether code is intended to be run as ES6 or not? Do let and const count as ES6 (retroactively applying to code using the old non-standard versions, which are still currently supported by V8 and Spidermonkey)? Does it apply to code that appears to use Map, WeakMap, and Set (though the code might well refer to shimmed versions of these and not otherwise expect to run as strict)?

Fair point that I should clarify: when I said ES6 features I really meant ES6 language constructs. Libraries are fine, of course.

So yes, 'let' and 'const' count as ES6. That doesn't keep implementations from providing them as sloppy mode language extensions as they do now, for their own backwards compatibility. There would be no reason to use those in new code, though.

One particular advantage of this is that we don't have to break the web for things like 'const' and 'function' in blocks. Existing implementations of those features are a horrible, inconsistent mess, but one that is dangerous to touch. Only cleaning it up in strict mode where we can safely do so (and remaining oblivious in sloppy mode) is likely to cause much less problems.

While there are many things that will absolutely indicate intention to run as ES6, there's a number of examples of ambiguity that make me doubt how successful an absolute judgment can be. This is why I think giving modules a double use as implicit opt-in/pragma has merit.

How does making certain constructs opt in implicitly resolve any of the ambiguities you mentioned?