Modules: import *

# Erik Arvidsson (11 years ago)

I know import * from ModuleSpecifier was cut to make the module proposal simpler. However, we still have export * from ModuleSpecifier which has most of implementation complications as import * does.

After using import * for over a year in Traceur ( google/traceur-compiler/commit/a8d919eda2d9d0ffd023c37b747cc979734cfaf2#diff-7b327c4c4229665f69afd29a46d100d2) I can tell you that it would be very painful to let go of it.

# Jason Orendorff (11 years ago)

On Thu, Oct 31, 2013 at 9:19 AM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

I know import * from ModuleSpecifier was cut to make the module proposal simpler. However, we still have export * from ModuleSpecifier which has most of implementation complications as import * does.

import * delays full knowledge of what's in the import lexical scope until link time. (That is, you can't figure out scopes by looking at a module in isolation. You have to wait for its dependencies.)

import * from "stickers";
...
    y = r * Math.sin(a);
...

It is unclear whether Math refers to the global Math or to something imported from "stickers" at least until "stickers" is loaded.

Similarly, export * from delays full knowledge of what's exported until link time. The practical difference is that a compiler can benefit from having static scope information up front. Exports really are not needed until link time.

# Erik Arvidsson (11 years ago)

Thanks, that makes sense.

On Thu, Oct 31, 2013 at 1:22 PM, Jason Orendorff <jason.orendorff at gmail.com> wrote:

import * delays full knowledge of what's in the import lexical scope until link time. (That is, you can't figure out scopes by looking at a module in isolation. You have to wait for its dependencies.)

import * from "stickers";
...
    y = r * Math.sin(a);
...

It is unclear whether Math refers to the global Math or to something imported from "stickers" at least until "stickers" is loaded.

You have to wait for "stickers" to load to validate the imports anyway.

Similarly, export * from delays full knowledge of what's exported until link time. The practical difference is that a compiler can benefit from having static scope information up front. Exports really are not needed until link time.

But it has a similar issue. You cannot look at a module in isolation and know what it exports.

# Jason Orendorff (11 years ago)

On Thu, Oct 31, 2013 at 12:40 PM, Erik Arvidsson <erik.arvidsson at gmail.com> wrote:

You have to wait for "stickers" to load to validate the imports anyway.

Right. Validating imports doesn't block compilation though. As long as you know at compile time that a given identifier is an import, you can just emit a load, and patch that load's target address at link time.

Or, if it's not an import: in the absence of import * from, the use of the identifier "Math" above could be compiled to code that does global.[[Get]]("Math"). SpiderMonkey does this today, when all enclosing non-global scopes are static, which is most of the time.

With import * from, we have dynamic scoping until link time—which is not the end of the world, but it sucks. Dynamic scoping sucks.

But all that is me speaking as an implementer. Humans looking at modules in isolation also benefit from being able to tell what names refer to.

[regarding export * from] But it has a similar issue. You cannot look at a module in isolation and know what it exports.

The issues are abstractly similar, but very different in practice. The effect of import * from on scoping depends on the version of the module you're importing. Collisions can occur in the future, as your code, the global object, and the imported module evolve. There's no way to mitigate.

The effect of export * from has no effect on scoping and no analogous risk of future collisions.

Now... good use cases could be a sufficient counterargument to all this. Maybe we should add import * from in 2014. I just want to make it totally clear why it's designed this way for ES6. import * from poses significant problems, both for users and implementations, that export * from doesn't.

# David Herman (11 years ago)

On Nov 1, 2013, at 7:44 AM, Jason Orendorff <jason.orendorff at gmail.com> wrote:

Now... good use cases could be a sufficient counterargument to all this. Maybe we should add import * from in 2014. I just want to make it totally clear why it's designed this way for ES6. import * from poses significant problems, both for users and implementations, that export * from doesn't.

Agreed. I do think there's a good change people will start asking for import * more once they've been using the module system, and we can revisit in ES7. There could also be additional technical challenges with lexical modules (if you can say import * from x there are weird scoping paradoxes that are hard to eliminate), so it makes sense to wait to reconsider import * until we're dealing with lexical modules.

Anyway, this will not be happening for ES6. Let's revisit for ES7.

# David Herman (11 years ago)

On Nov 1, 2013, at 6:19 PM, David Herman <dherman at mozilla.com> wrote:

I do think there's a good change

chance