<div class="gmail_quote">On Wed, Jan 26, 2011 at 5:04 PM, Brendan Eich <span dir="ltr">&lt;<a href="mailto:brendan@mozilla.com">brendan@mozilla.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

CommonJS may do that on the server side, assuming fast enough file i/o. It&#39;s not necessarily a good idea even there (Ryan Dahl has talked about this). On the client, it&#39;s right out, which is why client-side CommonJS-like module systems require a preprocessor or else a callback.<br>
<div class="im"></div></blockquote><div><br>There is work under way at CommonJS to rectify this problem. A few different proposals have emerged, which all have approximately the same theme:<br><ul><li> Explicitly decouple exports-lookup and module loading. </li>
<li> require() remains the exports-lookup interface </li><li> Introduce a way to know which modules are needed by a program, such as the explicit declaration of dependencies, or static analysis of the source code looking for require() statements.</li>
<li>Before the main module is executed, load all dependencies (recursively)<br></li></ul>Adding a mandatory function wrapper to the module source code also allows these modules to be loaded and executed directly by DOM script tag injection (an important technique as XHR has cross-domain restrictions); the function wrapper also provides a convenient place to hang dependencies.<br>
<br>Here is what a module in one proposal (Modules/2.0-draft7) looks like:<br><br><font size="1"><span style="font-family: courier new,monospace;">module.declare([<b>&quot;lib/dialog&quot;</b>], function(require, exports, module) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">  /* Any valid Modules/1.1.1 modules goes here */</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">  require(<b>&quot;lib/dialog&quot;</b>).notify(&quot;hello, world&quot;);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">})</span><br style="font-family: courier new,monospace;"></font><br>(Oh -- main-modules are modules which are executed automatically by the CommonJS host environment; e.g. by exec(3) shebang, HTML script tag, or other mechanism; the mechanism is not part of the specification)<br>
<br>I should also say that all the proposals also have a way to explicitly load a particular module at run-time, rather than via the dependency graph.  The interface specifies a module name (or names) and a callback. Once the module and its dependent modules are loaded, the callback is executed. This lets us do lazy-loading, like Simple Modules loaders, without breaking run-to-completion.<br>
<br> <br><br>On Wed, Jan 26, 2011 at 6:25 PM, Kam Kasravi <span dir="ltr">&lt;<a href="mailto:kamkasravi@yahoo.com">kamkasravi@yahoo.com</a>&gt;</span> wrote:<br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
Are you guys following modules 2.0 at all that seems to be a parallel universe of sorts under co mmonjs? <br></blockquote><br>Full disclosure - I am the principle author of that document. It is one of the proposals mentioned above. Its current status is &quot;pompously-named document designed to get attention&quot; - it is not a standard, and carries only the weight of the paper it is printed on. FWIW, it discusses much more than the CommonJS module system -- it also attempts to nail down the execution environment.  That said, there is no way Modules/2.0 belongs under consideration by TC39; it is a &quot;best-effort with limited tools&quot; proposal; Simple Modules gets to use new tools.<br>
<br><br><br>On Wed, Jan 26, 2011 at 5:40 PM, David Herman <span dir="ltr">&lt;<a href="mailto:dherman@mozilla.com">dherman@mozilla.com</a>&gt;</span> wrote:<br><blockquote style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class="gmail_quote">
Just to flesh this out a bit: simple modules were designed to make it 
possible to import and export variables into lexical scope, and to be 
compatible with checking valid imports and exports statically, as well 
as being able to check for unbound variables statically. Including, for 
example, in the case where you say<br><br>
    import M.*;<br><br>
Moreover, they are designed to allow loading modules *without* having to
 use callbacks, in the common case where they can be pre-loaded at 
compile-time.<br></blockquote>

<br>James&#39; query comes as attempt to understand design decisions made for Simple Modules with respect to the timing of the evaluation of the module factory function.  With loading and exports now decoupled, the question becomes -- when does require actually evaluate the module body?  The balancing point seems to be &quot;Is it worth breaking backwards compatibility on existing platforms in order to try and mimic Simple Modules?&quot;.<br>
<br>&quot;Breaking backwards compatibility&quot;, in this case, means evaluating the factories eagerly, as they are loaded into the environment as the dependency tree is satisfied (before the main module runs). Currently, factories are executed as side-effects of the first require() call (per module - our modules are singletons).  This timing is important, as factories have observable side effects (consider the module above).<br>
<br>So, what we&#39;re talking about is not just the Simple Modules loader, but the static declaration form as well.  Static declaration is analogous to loading a list of modules which is comprised of the main module and its recursive dependencies and then executing the main module.<br>
<br>FWIW - my take on this is that porting CommonJS to Simple Modules is going to require a code-audit anyhow; I believe that breaking backwards compatibility within the CommonJS family is not worth trying to mimic such a small sliver of Simple Modules semantics. There are much larger mismatches  (singletons, module-keyword, lexical scope, require() to name just a few) which make it a moot point IMO.<br>
<br>Kris Kowal&#39;s query is interesting: is lazy evaluation worth considering for Simple Modules?<br><br><font size="1"><span style="font-family: courier new,monospace;">   module M {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
        export var foo = 42;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
        export function bar() { return foo; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">      
 alert(&quot;hello, world&quot;);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">   }</span><br style="font-family: courier new,monospace;"></font><br>In the example above, the alert statement would occur when the first import from M statement were executed, rather than when the page containing the &lt;SCRIPT type=&quot;es-next&quot;&gt; were loaded.<br>
<br>Wes<br><br></div></div>-- <br>Wesley W. Garland<br>Director, Product Development<br>PageMail, Inc.<br>+1 613 542 2787 x 102<br>