Parsing allowed convenience in simple modules

# John J. Barton (15 years ago)

In strawman:simple_modules it says:

Module declarations are only allowed at the top level of a script or module, but for convenience, they can nest within top-level blocks, and are hoisted to be in scope for the entire containing script or module.

Can someone explain what this sentence means?

To me it says: Module declarations MUST be outside of any function declaration, but you can declare modules pretty much anywhere as long as you don't expect to understand what happens when you do ;-).

jjb

# David Herman (15 years ago)

Module declarations are only allowed at the top level of a script or module, but for convenience, they can nest within top-level blocks, and are hoisted to be in scope for the entire containing script or module.

Can someone explain what this sentence means?

To me it says: Module declarations MUST be outside of any function declaration, but you can declare modules pretty much anywhere as long as you don't expect to understand what happens when you do ;-).

Heh, that's not what it was supposed to mean, no. :) It means that you can only nest module declarations inside plain block statements -- not under conditionals, loops, functions, etc. For example:

<script type="harmony">
    {
        module C { ... }
        module D { ... }
    }
</script>

But I'm actually mostly convinced that allowing this little bit of nesting is a bad idea anyway. The reason this relaxation was put in there was to support REPL's, so that you could do multiline input with mutually recursive modules, e.g.:

js> {
    module A { ... B ... }
    module B { ... A ... }
}

But I think this introduces too much complexity into the spec just to support external tools, when those tools could probably pretty easily come up with their own solution. For example, a REPL like Firebug or node.js could add support for multi-line input with meta-commands such as:

node> .begin
...   module A { ... B ... }
...   module B { ... A ... }
...   .end

And allowing the nesting, coupled with hoisting, introduces all the usual headaches of hoisting like:

{
    let M = 12;
    {
        module M { ... } // oh God, now what?
    }
}

So having just explained this little detail, I'll now tell you that it's probably going away anyway. :)