Domenic Denicola (2012-12-28T15:20:03.000Z)
Now that I have fully digested Andreas's points from the earlier thread on modules [1], I am a bit concerned about the implications of `import` introducing aliasing bindings. To recap, the situation is:

module "foo" {
 export let state = 5;
 export function modifyState() {
   state = 10;
 };
}

import { state, modifyState } from "foo";

assert(state === 5);
modifyState();
assert(state === 10);

This is, to me as an ES5 programmer, very weird. There is *no other situation in the language* where what an identifier refers to can change without me assigning to it. Properties of objects, sure. But not bare identifiers. (Well, I guess `with` blurs this line. And the global object. No comment.)

This is compounded by the syntax used by `import`. The pseudo-destructuring microsyntax, plus the superficially declaration-like nature of that line, make you expect it to behave like a normal `let` or `var` declaration with destructuring assignment, which we are used to from CoffeeScript, Python, JS 1.8, etc. Obviously, it's a very different animal.

Notably, such aliasing is out of line with all current ES6 transpilers (Traceur [2], Six [3], Yehuda's js_module_transpiler [4]; TypeScript doesn't allow importing from modules, just importing module instance objects). Emulating such semantics would necessitate a desugaring that imports the module instance object, then rewrites all references to the imported identifiers to instead refer to properties of the imported module instance object. This is much more of a transformation than you'd expect, and of course falls down in the face of e.g. `eval("sta" + "te")`. The very fact that such a rewriting to object-property-access is necessary underscores how strange imported identifiers really are. I think people are in for a rude surprise moving from the transpiled world to the native ES6 world, and such semantics mean that a hybrid future---e.g. transpile for IE<=10, native for IE>=11---is laden with footguns waiting to be set off.

Finally, I can't shake the feeling I'm missing something. Why is this aliasing property valuable, given that it's so contradictory to expectations? I am totally on board with the need for static analysis and thus top-level-only import and export statements. The "just copy Node" peanut gallery is wrong, and the static analysis is not only necessary for asynchronous browser loading, but also adds a lot of power to the language. But what does the aliasing add? Is it connected to static analysis in some way I don't understand?

[1]: https://mail.mozilla.org/pipermail/es-discuss/2012-December/027021.html
[2]: http://tinyurl.com/ctvo8wr
[3]: https://gist.github.com/4347076
[4]: https://github.com/wycats/js_module_transpiler#individual-imports

P.S. One solution, if aliasing is indeed super-valuable, would be to move away from pseudo-destructuring microsyntax to one that's more alien, and thus connotes that something "strange" (or at least "unlike destructuring") is going to happen. Perhaps `import <state, modifyState> from "foo"`. This could be symmetrized on the export side: `export` takes a weird `ExportSpecifierSet` that looks something like an object literal, but behaves nothing like it, so maybe `export <state, modifyState>` would make this weirdness clearer.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121228/0c2179aa/attachment.html>
github at esdiscuss.org (2013-07-12T02:26:06.463Z)
Now that I have fully digested Andreas's points from the earlier thread on modules [1], I am a bit concerned about the implications of `import` introducing aliasing bindings. To recap, the situation is:

```js
module "foo" {
  export let state = 5;
  export function modifyState() {
    state = 10;
  };
}

import { state, modifyState } from "foo";

assert(state === 5);
modifyState();
assert(state === 10);
```

This is, to me as an ES5 programmer, very weird. There is *no other situation in the language* where what an identifier refers to can change without me assigning to it. Properties of objects, sure. But not bare identifiers. (Well, I guess `with` blurs this line. And the global object. No comment.)

This is compounded by the syntax used by `import`. The pseudo-destructuring microsyntax, plus the superficially declaration-like nature of that line, make you expect it to behave like a normal `let` or `var` declaration with destructuring assignment, which we are used to from CoffeeScript, Python, JS 1.8, etc. Obviously, it's a very different animal.

Notably, such aliasing is out of line with all current ES6 transpilers ([Traceur][2], [Six][3], [Yehuda's js_module_transpiler][4]; TypeScript doesn't allow importing from modules, just importing module instance objects). Emulating such semantics would necessitate a desugaring that imports the module instance object, then rewrites all references to the imported identifiers to instead refer to properties of the imported module instance object. This is much more of a transformation than you'd expect, and of course falls down in the face of e.g. `eval("sta" + "te")`. The very fact that such a rewriting to object-property-access is necessary underscores how strange imported identifiers really are. I think people are in for a rude surprise moving from the transpiled world to the native ES6 world, and such semantics mean that a hybrid future---e.g. transpile for IE<=10, native for IE>=11---is laden with footguns waiting to be set off.

Finally, I can't shake the feeling I'm missing something. Why is this aliasing property valuable, given that it's so contradictory to expectations? I am totally on board with the need for static analysis and thus top-level-only import and export statements. The "just copy Node" peanut gallery is wrong, and the static analysis is not only necessary for asynchronous browser loading, but also adds a lot of power to the language. But what does the aliasing add? Is it connected to static analysis in some way I don't understand?

[1]: https://mail.mozilla.org/pipermail/es-discuss/2012-December/027021.html
[2]: http://tinyurl.com/ctvo8wr
[3]: https://gist.github.com/4347076
[4]: https://github.com/wycats/js_module_transpiler#individual-imports

P.S. One solution, if aliasing is indeed super-valuable, would be to move away from pseudo-destructuring microsyntax to one that's more alien, and thus connotes that something "strange" (or at least "unlike destructuring") is going to happen. Perhaps `import <state, modifyState> from "foo"`. This could be symmetrized on the export side: `export` takes a weird `ExportSpecifierSet` that looks something like an object literal, but behaves nothing like it, so maybe `export <state, modifyState>` would make this weirdness clearer.