Ambiguity with default exports and live bindings?

/#!/JoePea joe at trusktr.io
Sun Jul 10 19:46:21 UTC 2016


I think I'm more confused than I thought. Are all bindings read only
always, only modifiable by exported functions/classes?

*/#!/*JoePea

On Fri, Jul 8, 2016 at 12:22 PM, /#!/JoePea <joe at trusktr.io> wrote:

> Interesting. I think it is very intuitive to think that `export default A`
> where `A` is a variable would be live. I personally find that live bindings
> are very helpful when dealing with circular dependencies.
>
> For example, suppose we have two modules A and B:
>
> ```js
> // B.js
> import A, {defineClassA} from `./A`
>
> if (!A) defineClassA() // this fires, and triggers the error, see A.js.
>
> export default
> class B extends A { /* ... */ }
> ```
>
> ```js
> // A.js
> import someFunction from './other-module'
> import B from './B'
>
> let A = null
> export default A
>
> if (!A) defineClassA() // this doesn't fire, the error is triggered by
> B.js first.
>
> export
> function defineClassA() {
>   someFunction() // Error happens here, triggered from B.js
>
>   A = class {
>     method() {
>       console.log('B constructor:', B)
>     }
>   }
> }
> ```
>
> I was erroneously expecting the export statements to create live bindings,
> so that my `defineClassA` call inside of B would cause A to be defined in
> case module B evaluates first. But as you can see, that doesn't work.
>
> So, I'll simply now prefer `export {A as default}`, in which case the
> modules become
>
> ```js
> // B.js
> import A, {defineClassA} from `./A`
>
> if (!A) defineClassA() // this fires, and triggers the error, see A.js.
>
> class B extends A { /* ... */ }
>
> export {B as default}
> ```
>
> ```js
> // A.js
> import someFunction from './other-module'
> import B from './B'
>
> let A = null
> export {A as default}
>
> if (!A) defineClassA() // this doesn't fire, the error is triggered by
> B.js first.
>
> export
> function defineClassA() {
>   someFunction() // Error happens here, triggered from B.js
>
>   A = class {
>     method() {
>       console.log('B constructor:', B)
>     }
>   }
> }
> ```
>
> Although I love ES6 modules, I don't think these live binding semantics
> are clear or intuitive. Although probably too late and it won't happen,
> what if export bindings were more explicit with a `live` keyword?
>
> ```js
> export {
>   live bar, // live binding of variable bar
>   foo // not live, exports value.
> }
>
> export // not live
> function foo() {}
>
> export live // live
> function foo() {}
>
> export default live A // A is a live binding
>
> export default A // exports value
>
> // etc...
> ```
>
> The reason I suggest this is because JS seems to prefer having meaningful
> keywords to make intent clear (for example, we chose to have the `await`
> keyword inside `async` functions, but we could have gone the Java route and
> used no keywords at all to make it hard to immediately see what is async
> and what isn't).
>
>
>
>
>
>
>
> */#!/*JoePea
>
> On Wed, Jul 6, 2016 at 4:38 PM, Bergi <a.d.bergi at web.de> wrote:
>
>> /#!/JoePea schrieb:
>>
>>> Is it true one of the following does not create a live binding?
>>>
>>
>> Yes and no.
>>
>> ```js
>>> let A = 123
>>> export default A // not a live binding?
>>> ```
>>>
>>
>> Actually it does create a live binding - to the variable with the name
>> "*default*" which you cannot assign. But yes, the binding `A` is not
>> exported.
>>
>> ```js
>>> let A = 123
>>> export {A as default} // live binding?
>>> ```
>>>
>>
>> Yes.
>>
>> If so, this seems like large source for unexpected behavior when people
>>> create modules. I can imagine people easily overlooking the difference
>>> and
>>> expecting live bindings in both cases (this already happened to me).
>>>
>>
>> I think people do in general not expect live bindings at all. For
>> declarations and the purpose of initialisation order, yes, but not for
>> mutable variables. You should export `const`s.
>> See also
>> http://stackoverflow.com/q/35223111/1048572?what-is-the-difference-between-importing-a-function-expression-or-a-function-declaration-from-a-ES6-module
>> .
>>
>> Kind regards,
>>  Bergi
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20160710/549bf377/attachment.html>


More information about the es-discuss mailing list