ES6 opt-in, reloaded

Claus Reinke claus.reinke at
Tue Jan 17 07:19:10 PST 2012

> So I'd have to write
>   use version 6;
>   module {...}
> instead of just
>   module {...}
> even though there's no backward compatibility issue? That's just mean! :-|

Why? Assuming that modules work out, they will be in ES7,8,.. as well.
So, 'module' isn't sufficient to identify ES6. At best, 'module' identifies
ESn (n>5). And that assumes that the feature will remain unchanged
for all ESns to come. I would not want to make that assumption even
for 'module', let alone for 'class'.

I like the idea of backwards compatibility, being able to run code for
the first PCs on processors design decades later. The more of that you
can pull off without cost, the better.

But not being able to throw anything away has a high cost. And I don't
think I want to give up on the idea of using ES6 to clean up some dark
corners of ES, just because someone doesn't want to have to write
'use ES6'. Client-side JS coders are already used to explicit opt-ins,
like 'doctype', to opt in to browser standard mode.

If you think (i.e., hope) that your ES6 code will work without issues
in ES7, you can leave out the 'use ES6' and let the engine choose
the current default version (if it happens to be an ES5 engine, bad
luck). If you want to document what version of ES your code is
_known_ to work with, you can use 'use ES6' (the ES7 engines
either knows how to handle that, or can give a sensible early
error/warning; ES5 engines will give a useful syntax error).

Versioning should be scoped, to reduce concatenation issues,
and the features we want put constraints on what level of version
scoping is possible/sane. Still, as a 0th approximation, one could
start with versioning to the next enclosing block/top-level, then
rule out complicated nestings of differently versioned blocks.

Versioning should also be modular: if I want to use 'yield', why
do I have to opt into all of ES6? There may be engines that support
'yield' but not yet (or no longer, or not at all) other features of ES6.

Modular/feature-based versioning would also help with your
fingers-of-fate problem: you don't want to introduce too many
changes so that coders don't get overwhelmed. But if coders
can opt in to ES6 features selectively, that is less of an issue.

So I would like to be able to say things like

    use yield, let, destructuring; // opt in to specific features

    use ES6;    // opt in to a standard collection of features

                      // no explicit opt-in means implicit opt-in to
                      // current default version

    use ES5;    // explicitly opt in to an old standard, in case
                      // engines, standards, and defaults move on

Based on Haskell experience again, every feature/opt-in should
have its negation/opt-out, as well:

    use ES6, !typeof-reform;    // code will mostly work in ES6,
                                        // but isn't ready for this feature

Fortunately, client-side JS coders have a lot of experience with
code versioning in the presence of rapidly changing feature sets,
and it is accepted best practice to do feature-testing instead of
the older practice of user-agent-version-number-testing.

So it isn't as if TC39 would have to introduce any completely
foreign ideas about versioning to JS coders - we only need to
translate the ideas into a form suitable for language feature

Do you really think that JS coders who start their codebase with
modernizr and the like, to figure out whether the features they
want to use are supported on the engine that runs their code,
will be scared away by documenting the language features
their code relies on?

> My non-speculative argument rests on experience on the web. Version
> marks and other separators are mangled and lost all the time.

The point is that explicit version marks can be pointed to, and
checked against the code ("your car and airplane should have
seatbelts - if not, change the dealer or airline"; "yes, even well
preserved old-timers are now supposed to have seatbelts"; "oh,
there it is, it just got mangled into that gap").

Implicit version marks use defaults, which change over time
or with context ("hmm, no-one else here seems to have seat-belts,
so that must be okay?"). At best, you'll have to remember what
the current defaults are and what the intended defaults were.
At worst, you'll be surprised.


> I believe we should offer well-defined <script type=...;version=...>
> opt-in for script content hiding from old UAs, and *in addition*
> belt-and-braces in-script-content version opt-in at a minimum, via some
> pragma such as |use version 6;|.

The latter would also work in eval-ed code.

> But I also believe these will be lost or simply not used, and adoption
> will be better if we define sensible (per your arguments against
> tainting from small to large extent) new-syntax-is-its-own-opt-in rules,
> per Dave's o.p.
> The reason I believe this is our experience in past edition shifts and
> experimental extensions. Usability wins should tax spec-editors (if not
> implementors -- let's not assume the implementation costs of implicit
> opt-in are too high [*]) for the greater good of the JS developers.


More information about the es-discuss mailing list