On ES.next features prototype implementations in web browsers

Brendan Eich brendan at mozilla.com
Mon Aug 15 12:22:23 PDT 2011

On Aug 5, 2011, at 7:47 AM, David Bruant wrote:

> Hi,
> We are seeing prototype implementations of ES.next features in browsers,
> namely Proxies on SpiderMonkey and V8. The former allows the use of
> proxies in HTML <script> tags with type="text/javascript", the latter
> apparently allows the use of proxies when running V8 with some flag
> (source: latest aminutewithbrendan [1]).

We've been extending JS in SpiderMonkey forever. Had we not, it's hard to say what would have happened. One anecote: getters and setters were something I added over a decade ago, such that when Firefox took enough share from IE that by 2005, the live.com properties (live maps, I believe) used getters and setters on Firefox to emulate IE's non-standard DOM. This caused very rapid reverse-engineering of getters and setters in Safari and Opera.

I'm not relating this to tell a story with a clean "moral". Some of this was accidental, but much of it was game theory. Had we hidden getters and setters behind a flag, I'm not sure what Microsoft's web developers would have done. Probably use an Ajax library that did not require IE DOM quirk emulation -- but DOM emulation and extension may entail getters and setters in any case.

Beyond this anecdote, the reason we surfaced extensions without always hiding them behind flags or opt-in versioning was two-fold:

1. To get user testing at scale. You can't do this with 1000 or 10,000 or even 100,000 users, especially with volunteer effect due to the flag or opt-in requiring web developer and geek skills.

2. To improve JS while Ecma TC39 was stagnating after ES3.

While the second reason is behind us, we now have a new reason to extend JS:

3. To prototype draft specs before finalizing them, in order to user-test them (1).

> I don't know if there are other ES.next features currently implemented
> and available with <script type="text/javascript">,

BTW, that's an unregistered MIME type hardcoded into HTML4. The registered type is application/javascript (also application/ecmascript). See RFC 4329.

> but i think it should be avoided.

You are not distinguishing API additions from new syntax.

API additions can in general be object-detected, and need no further opt-in or flagging.

There may be a special case: global properties such as Proxy, which are harder to detect and which may break existing scripts that detect the property name in question in order to polyfill their own implementation. This happened with JSON, in spite of the precedent of json2.js, but we persevered and the conflicting code's owners fixed their scripts (Facebook, IIRC).

New syntax may indeed require opt-in versioning, because of new reserved identifiers, especially 'let' and 'yield'. We had to try reserving these in unversioned scripts in 2006 and on in JS1.7+ to learn this. These two words are reserved in ES5 strict, but strict mode adoption is tiny and just starting.

Therefore, when it comes to APIs, I disagree, for the reasons 1 and 3 given above. Object detection is in general enough.

> IIRC, Harmony is supposed to be proposed as an opt-in
> (with a particular @type value is i remember well).

Please read RFC 4329:


There will be *at least* a ;version=6 parameter you can use, probably with either application/javascript and application/ecmascript -- I have argued that we should align version numbers.

But telling people to opt into use of prototype implementations of ES6 does not really help, because

A. The spec is subject to change while being drafted.

B. The spec's version number might change due to some ISO or Ecma non-technical need to advance whole version number.

We do not want to add version=6pre or other parameter values, I claim, since that will reduce user testing and increase the number of under-maintained, stale, misspelled, etc. version= parameters on the web.

Again for new syntax, opt-in by versioning may be necessary, otherwise new keywords will not be reserved. That opt-in by version= is already supported in Firefox:

  <script type="application/javascript;version=1.8">

allows the ... code to use let and yield.

Beyond the RFC 4329 version= parameter, we also want a pragma for in-script-content version assertion:

  use version 6;

This is invalid syntax in ES1-5. Of course developers do not want to ship such scripts to old browers, but they should want belt-and-braces protection against new script that does not use new syntax but depends on new runtime behavior that differs from ES1-3 and ES5 non-strict (ES5 strict and Harmony starting with ES6 have a few runtime semantic incompatibilities, as we have discussed on this list in the past).

So I expect some developers will use

  <script type="application/ecmascript;version=6">
    use version 6;

and (even more likely) an out-of-line variant that loads a version=6 script dyamically, in order  to opt into ES6 prototype implementations, if browsers start supporting this version prior to ES6 being finalized.

And I argue that browser vendors *should* do so, to encourage user testing and maximize feedback, including on interoperation with other browsers' prototype implementations, so that bugs in those implementations and in the draft specs can be found and fixed sooner than otherwise.

Any barriers beyond this will simply impair user testing and bug finding, reporting, and fixing.

The last thing we need are "vendor prefixes". These stink up CSS on the web for years and fail to go away on any schedule, even when the unprefixed style property has been standardized. I'm not saying vendor prefixes don't work well for CSS -- the CSS syntax including normative error correction supports such extensions better -- but the fact that vendor prefixes become de-facto standards and live way too long is self-evident.

Given the conditions of Harmony in TC39, I claim -- and observe based on work so far -- that we ought to be able to implement and interop test under the proposed names.

One more thought on names: with modules in ES6 it ought to be possible to avoid grabbing global names at all. E.g., users would declare

  module Proxy from "@proxy";

or even

  import {create, createFunction} from "@proxy";

And as Dave and Luke have discussed, even unversioned script could use Object.SystemLoader or some such reflection of the module loader API to load from "@proxy", "@name", etc.

> Maybe that this
> opt-in could be started now. If it isn't, people are going to use
> ES.next features with <script type="text/javascript"> which will prevent
> to switch back to an opt-in model.

Not so. Again, APIs can in general be object-detected, and this is enough. New syntax requires opt-in for 'let' and 'yield' at least, and belt-and-braces pragmas to defend against wrong-version loads of new-runtime-semantics scripts in old browsers.

> Maybe that type="text/es-next" could

No, not text/ -- application/ -- text/ is the wrong category. Please help kill this bogus idea from HTML4 in the '90s.

> be a value dedicated to experimental ECMAScript features before approval.
> I'm not entirely sure, but i think that there is already something like
> that on Firefox for chrome code (which allows to already use "const"
> without having the keyword available to web dev JS, for instance).

See above. We added const ages ago, no version opt in required. Other browsers implement const, but not all in the same way, which (as with function declarations in blocks) allows us to clean up with const-as-block-binding-form in Harmony.

Another problem: "application/es-next" or whatever is hopelessly ambiguous at web scale. We will likely get to an ES7. Old content under this proposed type would linger on, I guarantee it. Then what?

> I think that all browsers should agree on one type value (or a serie,
> like "text/v8-es-next", "text/spider-monkey-es-next"...
> "text/*es-next"...)

No, see above. This is a recipe for non-interoperation and delayed or lost bug reports, if not worse competitive speciation.

Again, we have a lot of experience with RFC 4329 style versioning in Mozilla. New APIs that can be object-detected in general need no extra opt-in. And the proposed 'use version 6' pragma needs to be developed.

Agreement among browsers to support ;version=6 in advance of the spec being finalized is a goal, which I will raise at the next TC39 meeting. We can discuss here first, of course.


> to expose their experimental features without making
> them available to web devs which use (implicitely or not)
> "text/javascript" on their webpage.
> David
> [1] http://www.aminutewithbrendan.com/pages/20110805
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

More information about the es-discuss mailing list