Globalization API working draft

# Norbert Lindenberg (14 years ago)

A working draft of the ECMAScript Globalization API Specification for review at the November TC 39 meeting is available at globalization:specification_drafts

There are still a number of open issues, and the algorithms still need significant work, but the internationalization ad hoc group would like to get the feedback of TC 39 on the overall shape and functionality of the API.

We've found that it's quite difficult to reverse-engineer the algorithms to deduce the rationale for them, so I'll try and follow up with more background in the next few days.

, Norbert

# Erik Arvidsson (14 years ago)

The draft has the following:

6 The Globalization Object

The Globalization object is a single object that has some named properties, all of which are constructors.

The value of the [[Prototype]] internal property of the Globalization object is the built-in Object prototype object specified by the ECMAScript Language Specification. The value of the [[Extensible]] internal property is false.

This seems very bad and counter intuitive to how the web works. It would mean that there is no way to fix the Globalization object for browsers that are not fully up to date. Lets assume that in a future version of the spec the Globalization object gains a new property. The standard way to handle this in JS is to do:

if (!Globalization.newProperty) { Globalization.newProperty = ...; }

This allows people to migrate to new features and it is how people gradually started to use Array extras.

# Nebojša Ćirić (14 years ago)

We were told (I think by Allen) that setting [[Extensible]] to true would conflict in some way with ES6 modules. I do agree it's a big restriction to set it to false given how JavaScript works today.

So the question is - are we going to have problems with ES6 Modules is we set this property to true? If so, is there another way of solving this problem?

  1. новембар 2011. 14.12, Erik Arvidsson <erik.arvidsson at gmail.com> је написао/ла:
# Brendan Eich (14 years ago)

On Nov 2, 2011, at 3:00 PM, Nebojša Ćirić wrote:

We were told (I think by Allen) that setting [[Extensible]] to true would conflict in some way with ES6 modules. I do agree it's a big restriction to set it to false given how JavaScript works today.

So the question is - are we going to have problems with ES6 Modules is we set this property to true? If so, is there another way of solving this problem?

Do you mean, are you (or all of us working on Ecma TC39 standards) going to make Globalization name an ES6 module? But that doesn't seem necessary. Users should declare

module G11N from "@g11n";

or

import {foo, bar, baz} from "@g11n";

and name the module in whatever scope they want.

If we try to pre-declare the module and force the name to "Globalization", then I agree with Erik -- not only are we making it hard to polyfill for v2 when running

# Allen Wirfs-Brock (14 years ago)

On Nov 2, 2011, at 3:00 PM, Nebojša Ćirić wrote:

We were told (I think by Allen) that setting [[Extensible]] to true would conflict in some way with ES6 modules. I do agree it's a big restriction to set it to false given how JavaScript works today.

So the question is - are we going to have problems with ES6 Modules is we set this property to true? If so, is there another way of solving this problem?

I do recall that we talked about this at the meeting held at Google, but I don't remember the details. I'm pretty sure that my first reaction would have been the same as Erik's but we also did talk about module implications.

Ideally, the globalization support would manifest as a global (or properties on an existing global) in ES5 implementations and as a module in ES.next. Do we know how to actually make that work?

I think we probably have an interesting question for Dave and Sam about how to support version evolution of modules. Is there a module equivalent of monkey patching. What if we have an implementation that exposes a "V1" module (particularly a built-in module) and code that depends upon upon a V2 of that same module that has an expanded export list. Is there anyway for that code to patch the module to add the extra exported APIs it would like to use?

# Brendan Eich (14 years ago)

On Nov 2, 2011, at 4:09 PM, Allen Wirfs-Brock wrote:

Ideally, the globalization support would manifest as a global (or properties on an existing global) in ES5 implementations and as a module in ES.next. Do we know how to actually make that work?

What we did talk about was exposing the system loader to unversioned script through an API, say Object.System. Then you could Object.System.load("@g11n" ...) and get stuff done. The built-ins should not require a callback

# Nebojša Ćirić (14 years ago)

My main concern at the moment is ES5. It seems that best practice is to declare [[Extensible]]:true, which would in turn avoid conflicts with pre-existing globals and let developers append new functionality to Globalization. We can deal with modules in the future revisions if necessary.

  1. новембар 2011. 16.20, Brendan Eich <brendan at mozilla.com> је написао/ла:
# Brendan Eich (14 years ago)

On Nov 2, 2011, at 4:51 PM, Nebojša Ćirić wrote:

My main concern at the moment is ES5. It seems that best practice is to declare [[Extensible]]:true, which would in turn avoid conflicts with pre-existing globals and let developers append new functionality to Globalization. We can deal with modules in the future revisions if necessary.

That's a fine approach if you really are making a spec that adds onto ES5. Depends on timing.

# David Herman (14 years ago)

I think we probably have an interesting question for Dave and Sam about how to support version evolution of modules. Is there a module equivalent of monkey patching. What if we have an implementation that exposes a "V1" module (particularly a built-in module) and code that depends upon upon a V2 of that same module that has an expanded export list. Is there anyway for that code to patch the module to add the extra exported APIs it would like to use?

ES6 modules are not extensible, for a number of reasons including compile-time variable checking. But of course API evolution is critical, and it works; it just works differently. Monkey-patching says "let the polyfill add the module exports by mutation," e.g.:

// mypolyfill.js
...
if (!SomeBuiltinModule.newFeature) {
    load("someotherlib.js", function(x) {
        SomeBuiltinModule.newFeature = x;
    });
}

you instead say "let the polyfill provide the exports," e.g.:

// mypolyfill.js
...
export let newFeature = SomeBuiltinModule.newFeature;
if (!newFeature) {
    load("someotherlib.js", function(x) {
        newFeature = x;
    });
}

The difference is that clients import from the polyfill instead of importing from the builtin module. I'm not 100% satisfied with this, but it's not any more code than monkey-patching.

# Andreas Rossberg (14 years ago)

On 3 November 2011 01:12, David Herman <dherman at mozilla.com> wrote:

ES6 modules are not extensible, for a number of reasons including compile-time variable checking. But of course API evolution is critical, and it works; it just works differently. Monkey-patching says "let the polyfill add the module exports by mutation," e.g.:

// mypolyfill.js    ...    if (!SomeBuiltinModule.newFeature) {        load("someotherlib.js", function(x) {            SomeBuiltinModule.newFeature = x;        });    }

you instead say "let the polyfill provide the exports," e.g.:

// mypolyfill.js    ...    export let newFeature = SomeBuiltinModule.newFeature;    if (!newFeature) {        load("someotherlib.js", function(x) {            newFeature = x;        });    }

The difference is that clients import from the polyfill instead of importing from the builtin module. I'm not 100% satisfied with this, but it's not any more code than monkey-patching.

I believe the more modular and more convenient solution (for clients) is to create an adapter module, and let clients who care about new features import that instead of the original builtin. With module loaders, you should even be able to abstract that idiom away entirely, i.e. the importing code doesn't need to know the difference. It is easy to maintain such adaptors as a library.

This is a common approach in module-based languages. It is a more robust solution than monkey patching, because different clients can simply import different adapters if they have conflicting assumptions (or, respectively, have a different loader set up for them).

One issue perhaps is that the modules proposal doesn't yet provide a convenient way to wrap an entire module. Something akin to "include" in ML, which is a bit of a two-edged sword, but perhaps too useful occasionally to ignore entirely.

# David Herman (14 years ago)

Yes, good point about loaders. I would like a standard HTML way of specifying a loader to use, so you could simply say:

<meta loader="polyfill.js"/>

and from then on your clients don't have to change a thing.

# Axel Rauschmayer (14 years ago)

Can loaders be composed (e.g. to use several polyfills at the same time)? One might be able to chain them in some fashion.

# David Herman (14 years ago)

Possibly, although it could be tough; I'll keep this in mind as we nail down the API details.

# Axel Rauschmayer (14 years ago)

Alternative for polyfills: A loader that maps module names to alternate implementations. This reminds me of dependency injection.

Potential problem: The path of a (non-built-in) library might not always be a good ID (one module loads a minified version, another doesn’t). Maybe we need some kind of optional separate module ID.

# Norbert Lindenberg (14 years ago)

A guide and background article is now available: norbertlindenberg.com/2011/11/ecmascript-globalization-api/index.html

, Norbert

# Norbert Lindenberg (14 years ago)

And now we also have a bugzilla product into which you can report issues found in the specification: bugs.ecmascript.org/enter_bug.cgi?product=ECMAScript Globalization API

Items that may need discussion among a larger audience should still go to es-discuss at mozilla.org.

Thanks, Norbert