Modules: compile time linking (was Re: Modules feedback, proposal)

James Burke jrburke at gmail.com
Thu Apr 5 10:01:36 PDT 2012


On Sat, Mar 31, 2012 at 6:47 PM, David Herman <dherman at mozilla.com> wrote:
> Static checking is a continuum. It's mathematically proven (e.g., Rice's theorem) that there are tons of things a computer just can't do for you in general. So we have to pick and choose which are the things that can be done for us that are a) decidable, b) tractable, and c) useful. In my experience, checking variables is really useful, even though it certainly can't check every aspect of a program's correctness.

I would add d) does not compromise other high value features. For me,
one would be runtime module opt-in by code that also wants to work in
non-ES.next environments.

If there are reasons not to treat that as a high value feature, that
probably changes my feedback.

However to be clear, I would like more name/typing checking, and the
ability to use something like "import *".

So to try to get a decent pass at all of those benefits, could the
following evaluate/compile model be used:

# Example:

module Foo {
    import * from 'Math';
}

# Rules:

* The 'Math' module is evaluated before Foo is evaluated.

* Only the properties on Math that are available at the time of Foo's
execution are bound
to local variables via the "import *".

So, assuming Math has no dependencies (just to make this shorter), the
sequence of events:

* Load Foo, convert to AST, find "from" usage.
* Load Math
* Compile Math
* Evaluate Math
* Inspect Math's exported module value for properties
* Modify the compiled structure for Foo to convert "import *" to have
local variables for all of Math's properties that are known, only at
this time (no funny dynamic 'with' stuff)
* Evaluate Foo

I may not have all the right terminology, in particular "convert to
AST/work with compiled structure" may not be correct, but hopefully
the idea comes across.

# Benefits:

* It is not "with" or its ilk.

* Allows both "top level" module export name/type checking and "second
level" checking since more info on Math is available after running
Math, including info prototypes on for any constructor functions.

* Opens up allowing opt-in to ES.next modules and still be run in old
world browsers.

* Still seems to allow for some kind of macros and operator overloading later?

# Possible hazards:

* Something could modify Math's properties before a different module
Bar is run, and Bar might see different * bindings than Foo. This
happens with JS now though -- depending on when you execute a
function, it may see different properties on objects it uses.

* Too many processing stages?

* Circular import * is a problem. This could be flagged as an error
though. Circular dependencies are minority cases (import * of this
case even smaller), and the benefit of opening up second level
name/type checking and runtime module opt-in may be worth the
tradeoff.

James


More information about the es-discuss mailing list