simple modules

Mark S. Miller erights at
Tue Feb 2 17:16:55 PST 2010

On Fri, Jan 29, 2010 at 5:13 PM, David Herman <dherman at> wrote:

> We had a good discussion about modules at this week's meeting, and Sam
> Tobin-Hochstadt and I have worked out a strawman for a simple module system.
> I've posted a first draft to the wiki:
> There are lots of examples to peruse at:
> which might also be a decent starting point to get a feel for the design.
> This has a good bit of overlap with -- and is in many ways inspired by --
> Ihab and Chris's work, but it has at least one major departure: modules in
> this proposal are not inherently first class values, although we do provide
> ways of getting objects that reflect the contents of modules.
> This is just a draft, and we'll be revising it as we go along. But I'm
> happy to take any feedback people have. Also, please let me know what's
> unclear. I'll try to both clarify on es-discuss and revise the page
> accordingly.
Hi Dave and Sam,

I have now read the strawman and example pages carefully. I have not yet
read this thread carefully, though I have skimmed it. Excuse me if some of
my comments are redundant with or obsoleted by earlier messages. Given the
agreement just now on the list, I have read your docs with this agreement in
mind and found no conflicts.

* You list "Dynamic upgrade" in the goals and then mention it again in a
TBD. I do not understand how this proposal could be stretched to accommodate
dynamic upgrade. I also do not think this is a criticism. I only mention it
since it is one of your goals.

* I find your import syntax too complicated and too redundant with other
concept already on the proposals page. Given <>, I would
define your ImportDeclaration as

    ImportDeclaration ::= 'import' Pattern 'from' ModuleSpecifier ';'

First, the trivial issue. The ES5 grammar specifies semicolons as literal
semicolons as above and leaves it to other language to specify semicolon
insertion rules. Your grammar says "(';')?", which confuses the issue. I
assume this was either just informal or a typo.

With the above grammar, we no longer need your ImportSpecifier or
ImportDeclarator productions. And we can also avoid YET ANOTHER OVERLOADING
OF COLON. (Please keep in mind that type-like declarations probably will
overload colon, so please let's keep it to a dull roar. Perhaps we should
use '=' instead of 'from', in order to make the import production be more
obviously an additional binding form.

   Your....                    Becomes....

   import "Math" as M          import M from Math
   import "Math": sum, pi      import {sum, pi} from Math
   import "Math": sum as sam   import {sum: sam} from Math

I do not like open import for the reason Mike Samuel stated: adding an
exported symbol to Math should not break existing clients of Math. If all
those clients only do closed import as above, it won't. If they do open
imports from Math and one other module, then the newly exported name may
conflict with another open import, breaking existing clients. Granted, they
break with an early error, but still. In any case, *if* we do want open
import, I think a better syntax is

   Your....                    Becomes....

   import "Math"               import {*} from Math

or perhaps

   import "Math"               import * from Math

The use of * for open import will be instantly familiar to Java programmers
(and instantly alarming to Java programmers like me who have learned to be
alarmed by it).

Note that open issue is not a security issue per se, and has nothing to do
with SES vs Harmony. It is purely a software engineering
and maintenance issue.

I do not understand why the ModuleSpecifier may be a list of strings. A list
of strings is less than you need to express where/how to find and verify
that a source file may be the thing you intend to designate. Such lookup
strategy issue should be internal to the module resolver. I like Ihab's
packaging notion of a catalog, used to provide a module resolver with a
mapping from simple module ids to potentially complex descriptions of
where/how/verify. Given a catalog, a list of strings is more than you need
for indexing into a cataloged description. A single module id should be

With a ModuleSpecifier being a single module id, it could be an Id
production rather than a StringLiteral (as also shown above).

For your Module production, what is the purpose of the Id after the "module"
keyword? After all, the module resolver is already assumed somehow able to
find a named module by other means, such as its location.

I thought your notion of Script vs Module was interesting and probably
right. It had not occurred to me to have them coexist in this way.

* Since the most often exported thing will be functions (and in SES the only
thing), should we allow

    ExportDeclaration ::= 'export' Id '(' Params_opt ')' '{' FunctionBody

as a shorthand for defining, freezing, and exporting a function?

* By "VariableStatement", do you intend to include "const" and "let"
declarations? These cannot be grouped into the same production because

    if (e1) var x = 1;

is fine but

    if (e1) let x = 1;

must be disallowed since lets don't hoist.

* What is "modes for this"? You never again use "mode" in this manner.

* Glad to see a TBD for creating new module resolvers. I think this is an
important open issue.

* I am very confused by your discussions of cyclic imports. How do you
propose that a module instance object's exported property return undefined
until its corresponding exported const variable is bound? For exported var
variables, this makes sense, since var variables are immediately readable as
undefined. For functions, of course, there's no problem; and therefore for
SES there's no problem. But const and let variables normally have a read
barrier, which throws on early read. I would hope to see this reflected in
the module system. For example, if a

    export const x = 8;

were in effect

    // at top of module
    Object.defineProperty(magicPreregisteredExports, 'x', {
      get: const() {return x;},
      enumerable: true

    // at original location
    const x = 8;

then an early attempt to read this property from the module instance object
-- including by pattern matching -- would throw rather than silently give
the wrong value.

* Is the "can" in

    But their properties can be explicitly updated in ECMAScript code, they
cannot receive new properties, etc.

a misspelling of "cannot"?

* In your optimization opportunities, you suggest that an

    module A {
      import "B";
      // do stuff

could start executing once the module resolver knows it can resolve B but
before it knows whether B itself will have an early error. This implies that
the semantics of importing a module with an early error is not that the
importing module itself has an early error. What alternative semantics for
B's early error do you suggest for A? (There is a parenthetical comment that
might be about this at the beginning of "Dynamic module loading". But I
don't know since I didn't understand it either.)

Example document

* What does the fragment in

    import ''


* What is "offline ES"? Do you mean server-side?

* I really like your "DM.make(Dom)" example. Good show.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list