On Tue, Oct 16, 2012 at 7:10 PM, David Herman <[email protected]> wrote:
> On Oct 16, 2012, at 4:51 PM, John J Barton <[email protected]>
> wrote:
...
>
> Concrete example: Even and Odd modules refer to each other, but the import
> statements occur after some initialization:
>
> module Odd {
> export let odd = function(x) {
> return x === 0 ? false : !even(x - 1);
> }
> import even from Even; // force execution of Even here, if it hasn't
> already
Ah, I see the import has three possible duties here, 1) declaration of
|even| from Even 2) definition of |even| 3) execution of module code.
Its that last category that cause the issues in this example: the
circular value isn't used until the next stmt.
> export let b = odd(17);
> }
> module Even {
> export let even = function(x) {
> return x === 0 || !odd(x - 1);
> }
> import odd from Odd; // force execution of Odd here, if it hasn't
> already
> export let b = even(17);
> }
> console.log(Odd.b);
>
> With semantics (a), this executes like so:
>
> - start executing Odd
> - initialize Odd.odd
> - start executing Even
> - initialize Even.even
> - try to start executing Odd (but it's already started, so don't)
> - initialize Even.b by calling Even.even
> - initialize Odd.b by calling Odd.odd
>
> And everything succeeds. With semantics (b), regardless of how we break the
> tie in a cycle, this will fail, because it will try to call either Odd.odd or
> Even.even before it has initialized the function. Say it starts executing Odd
> first. It would do this:
>
> - start executing Odd
> - initialize Odd.odd
> - initialize Odd.b by calling Even.even
> - error: Even.even is not yet initialized
>
> So semantics (a) makes it more possible to make a cyclic dependency work, but
> it's still subtle if you're trying to let them refer to each other in
> top-level initialization code: you have to make sure to carefully place the
> imports late enough that the relevant pieces of each modules will have
> adequately initialized.
I'm surprised by (b). A behavior I would expect from a module loader (c)
- start executing Odd
- initialize Odd.odd
- start executing Even
- initialize Even.even
- try to start executing Odd
- error: Odd has not completed (circular).
Unlike (b) we load and execute Even until we discover the cycle. (b)
seems to declare Even.even but rely on some other mechanism to define
it.
I guess that all three allow Even/Odd cycles without the execution of b.
I guess (a) excludes later standardization of (b) or (c) but not the reverse.
jjb
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss