Lexical Modules Can't Wait

# Kevin Smith (12 years ago)

I think we can all agree that, in principle, program structures which have scope and define a namespace should be lexically identified and should nest, unless there is some compelling reason otherwise.

A module, for any sane definition of the term in the context of Javascript, has a scope and defines a namespace. Therefore, unless we can provide some overwhelming argument to the contrary, established design principles tell us that modules should be lexically identified and should nest.

It has been suggested that we can postpone adding lexical modules until ES7. But to do so would be to postpone conceptual integrity, which is not an available option.

By postponing at-names, for example, we only postpone the usability of symbols-as-property-names. But by postponing lexical modules, we postpone the clarity of our design. Indeed, there is nothing in ES6 which requires more conceptual clarity than modules. Modules should be the mountain stream of ES6, because with modules we go from a splat of script tags, to a universe of connected systems.

Finally, there are actual use cases which require lexical modules. Let's say that I want to develop a library where each module lives in its own source file. And let's say that I only want to expose a "main" module, and hide the rest. Without lexical modules, there is no straightforward build process capable of encapsulating those internal modules.

# Mark S. Miller (12 years ago)

On Mon, Apr 15, 2013 at 6:41 AM, Kevin Smith <zenparsing at gmail.com> wrote:

I think we can all agree that, in principle, program structures which have scope and define a namespace should be lexically identified and should nest, unless there is some compelling reason otherwise.

A module, for any sane definition of the term in the context of Javascript, has a scope and defines a namespace. Therefore, unless we can provide some overwhelming argument to the contrary, established design principles tell us that modules should be lexically identified and should nest.

It has been suggested that we can postpone adding lexical modules until ES7. But to do so would be to postpone conceptual integrity, which is not an available option.

Hi Kevin, if nothing in the ES6 module system precludes lexical modules, why is postponing lexical modules and conceptual integrity till ES7 not an option? In the same sense, we likewise postponed most of what is needed for classes to have conceptual integrity (as well as literal integrity ;)) till ES7. And the lexical scope cleanups in ES5/strict, in the same sense, didn't have conceptual integrity until the const/let/modules of ES6. We can't get agreement on everything at once. Sometimes, we need experience with the things we do get agreement on to inform the discussions about the remainder.

That said, I mostly agree with you on modules. I agree with everything you say here. I say "mostly" only because I believe that modules definitions should be allowed in any lexically nested context. When appearing in a multiply-instantiated lexical context, such as the body of a function, the module definition should itself be multiply instantiable (or generative) as well. This has been true for all defining forms in JavaScript, and it has been a great virtue. However, I don't actually have a coherent end-to-end proposal for making this work (< strawman:simple_module_functions>

doesn't work), and it is clear that I could not agreement on one at the present time even if I had one.

Moving a consensus forward takes patience, and a sense of which starting steps may productively lead to which paths. ES6 is mostly settled. We should already be focussing most of our unrealized design ambitions on ES7.

# Andreas Rossberg (12 years ago)

On 15 April 2013 17:13, Mark S. Miller <erights at google.com> wrote:

On Mon, Apr 15, 2013 at 6:41 AM, Kevin Smith <zenparsing at gmail.com> wrote:

I think we can all agree that, in principle, program structures which have scope and define a namespace should be lexically identified and should nest, unless there is some compelling reason otherwise.

A module, for any sane definition of the term in the context of Javascript, has a scope and defines a namespace. Therefore, unless we can provide some overwhelming argument to the contrary, established design principles tell us that modules should be lexically identified and should nest.

It has been suggested that we can postpone adding lexical modules until ES7. But to do so would be to postpone conceptual integrity, which is not an available option.

Hi Kevin, if nothing in the ES6 module system precludes lexical modules, why is postponing lexical modules and conceptual integrity till ES7 not an option? In the same sense, we likewise postponed most of what is needed for classes to have conceptual integrity (as well as literal integrity ;)) till ES7. And the lexical scope cleanups in ES5/strict, in the same sense, didn't have conceptual integrity until the const/let/modules of ES6. We can't get agreement on everything at once. Sometimes, we need experience with the things we do get agreement on to inform the discussions about the remainder.

It's not as simple, though. If the alternative that currently is on the table has serious issues, then putting it into the language -- especially as the only mechanism -- will set a precedence for what many programmers henceforth consider idiomatic. We know how difficult (or rather, impossible) it is to deal with such bad legacy once it has spread.

# Kevin Smith (12 years ago)

Hi Kevin, if nothing in the ES6 module system precludes lexical modules, why is postponing lexical modules and conceptual integrity till ES7 not an option? In the same sense, we likewise postponed most of what is needed for classes to have conceptual integrity (as well as literal integrity ;)) till ES7. And the lexical scope cleanups in ES5/strict, in the same sense, didn't have conceptual integrity until the const/let/modules of ES6. We can't get agreement on everything at once. Sometimes, we need experience with the things we do get agreement on to inform the discussions about the remainder.

With ES5/strict, you had severe constraints on new syntax. With classes, we still don't have a solid, agreed-upon way to represent private instance state. These are real constraints which have a real impact on what can be done in the relevant timeframe. Is there a similar constraint with lexical modules?

Furthermore, it may be that by postponing lexical modules we end up introducing features which we don't actually need:

Take this form, whose purpose is to allow for concatenation of modules into a single file:

// The "GlobalReg" form
module "module-name" { }

If we have lexical modules, is this form truly necessary? I think not. Given nested modules, we can create a tool which, for some "root" module R, bundles R with all of R's dependencies in a way that completely encapsulates those dependencies. This encapsulation is not even possible with the GlobalReg form. The follow gist shows such a transformation:

gist.github.com/zenparsing/5355927

What's more, the GlobalReg form is very likely going to lead developers toward a practice of actually coding in that form. This will undoubtably lead to yet another variation of global namespace pollution, as libraries opportunistically register themselves under some single-word module name:

// Another form of global namespace pollution:
module "jquery" { ... }

There is a very real possibility that by postponing our work on lexical modules we will have inadvertently created a problematic namespacing legacy which we cannot get rid of.