Jason Orendorff (2013-11-01T14:44:23.000Z)
On Thu, Oct 31, 2013 at 12:40 PM, Erik Arvidsson
<erik.arvidsson at gmail.com> wrote:
> On Thu, Oct 31, 2013 at 1:22 PM, Jason Orendorff <jason.orendorff at gmail.com>
> wrote:
>>     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.

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.

-j
domenic at domenicdenicola.com (2013-11-02T19:22:55.016Z)
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.