Module system strawpersons

Mike Samuel mikesamuel at
Mon Jan 18 15:39:28 PST 2010

My understanding is that in a simplified example:
    module A:  function getB() { return (import 'B')(); }
    module B:  function getA() { return (import 'A')(); }
    main : window.onload = (import 'A')().getB;
where "main" is a module loaded via <script>(import
'main')()</script>, the following happens
(1) browser parses script body, sees import of 'main'
(2) browser starts fetch of 'main' and suspends script execution until
'main' is satisfied
(3) browser receives 'main' content and sees import of 'A'.  browser
has the option of starting fetching 'A'
(4) browser marks 'main' satisfied.
(5) browser starts instantiating 'main', and reaches (import 'A').  It
must suspend execution if 'A' has not been satisfied ; i.e. if 'A' is
not already in the cache due to prefetching or previous network
(6) once 'A' has been satisfied, it can start instantiating 'A', at
which point it could optionally prefetch 'B'.
(7) at some point the onload event fires which will suspend execution
until 'B' has been satisfied
(8) 'B' can be satisfied without any further prefetching because 'A'
has already been satisfied.

So the prefetching can be done or not depending on how many network
connections are filled with other things, but the instantiation is
done only when control reaches the "import" operator.

2010/1/18 Kam Kasravi <kamkasravi at>:
> Ok, cool!
> So the import framework could go about fetching A then B or B then A for any
> 3rd object that was going to
> use them. I know that YUI 3 does this type of loadiong explicitly, in this
> case would the import framework would take
> care of it or would there still need to be something the developer would do
> to get A and B early?
> I wasn't sure going thru the 'pim' function in Ihab's strawman where it was
> finding the dependencies or was getting help from the js runtime or
> something.
> thx
> Kam
> ________________________________
> From: Mike Samuel <mikesamuel at>
> To: Kam Kasravi <kamkasravi at>
> Cc: Andy Chu <andy at>; kkasravi <kkasravi at>; Brendan Eich
> <brendan at>; es-discuss <es-discuss at>
> Sent: Mon, January 18, 2010 2:44:48 PM
> Subject: Re: Module system strawpersons
> 2010/1/18 Kam Kasravi <kamkasravi at>:
>> Hi Mike
>> The former but not in the way you've described. Rather
>> module A:
>> this.getB= function() {
>>   return new (import 'B')();
>> }
>> module B:
>> this.getA = function() {
>>   return new (import 'A')();
>> }
>> If modules eagerly resolve imports then the above circular dependency
>> would
>> be a problem.
>> If modules lazily resolve imports then the above circular dependency would
>> be ok.
>> If catch-alls were used then proxy's would be used and the circular
>> dependency would be ok.
>> Current js has many examples of circular dependencies which are resolved
>> by
>> lazy evaluation.
> Ok.
> Ihab's proposal allows eager fetching, and mandates lazy
> instantiation, so the above example is not a problem with Ihab's
> proposal.
>> Kam
>> ________________________________
>> From: Mike Samuel <mikesamuel at>
>> To: Kam Kasravi <kamkasravi at>
>> Cc: Andy Chu <andy at>; kkasravi <kkasravi at>; Brendan Eich
>> <brendan at>; es-discuss <es-discuss at>
>> Sent: Mon, January 18, 2010 1:50:15 PM
>> Subject: Re: Module system strawpersons
>> I don't quite understand what is meant by circular dependencies in this
>> context.
>> Are you talking about the graph of imports, or the graph of module
>> instances?
>> If the former, how is it a problem?
>> If the latter, how could it occur without explicit user intent : a
>> module explicitly passing itself to a dependency?
>> E.g. in the former
>>   // fib.js
>>   var self = (import "fib.js");
>>   if (n < 2) { return n; }
>>   return self({ n: n - 2 }) + self({ n : n - 1 });
>> a module imports itself, and recursively invokes separate instances
>> which is stupid but does not result in a module being observed in a
>> partially initialized state.
>> In the latter:
>>     // foo.js
>>     var otherModuleMaker = (import "bar.js")({ baz: this });
>> module foo is explicitly allowing otherModuleMaker to observe it in an
>> uninitialized state.
>> 2010/1/18 Kam Kasravi <kamkasravi at>:
>>> Andy
>>> yes I was referring to the circular dependency issue.
>>> Catch-alls would be useful for this, though it would be nice if
>>> they were automated, eg returning a proxy until the module was used.
>>> Doing it manually by developer would be too difficult.
>>> I realize modules are intended to just satisfy a function body and
>>> can be initialized as objects or called as functions, but since they
>>> have strong container semantics I wonder if they should
>>> have more than just an 'id' especially if they provide a gateway
>>> to what else is in the directory as in commonjs.
>>> Kam
>>> ________________________________
>>> From: Andy Chu <andy at>
>>> To: Kam Kasravi <kamkasravi at>
>>> Cc: Brendan Eich <brendan at>; kkasravi <kkasravi at>;
>>> es-discuss <es-discuss at>
>>> Sent: Mon, January 18, 2010 12:40:35 PM
>>> Subject: Re: Module system strawpersons
>>> On Mon, Jan 18, 2010 at 10:29 AM, Kam Kasravi <kamkasravi at>
>>> wrote:
>>>> Yes, that looks right, I also remember a reference to the 'dot' notation
>>>> where namespace
>>>> access would be arbitrated implicitly by objects representing the '.' It
>>>> may
>>>> have been in
>>>> one of Lars Hansen papers on gradual typing. In any case there was some
>>>> good
>>>> discussion
>>>> on meta-level objects and controlling capabilities or access.
>>>> Was there any discussion in the past about parameterized modules or
>>>> units where recursively nested modules/units were brought up? If two
>>>> modules
>>>> refer to each other
>>>> and all imports are resolved eagerly then I think this would be a
>>>> problem
>>>> where use cases would
>>>> abound.
>>> What are you referring to here?  I think you are hinting at the
>>> problem of circular dependencies using "import" semantics like Python
>>> and CommonJS.  Right now if you have mutually recursive modules, you
>>> get partially initialized modules, because the "program counter" just
>>> follows every require().  The CommonJS spec specifically allows the
>>> partially initialized modules I think.
>>> Personally I try to break up circular dependencies, but this behavior
>>> is not very friendly, so I think it would be better if Harmony
>>> supported circular dependencies in a more "correct" way.  So this is
>>> an advantage of the "makers" style semantics (separating module
>>> definition and configuration).
>>> The Newspeak paper talks explicitly about this:
>>> If you are initializing modules in topological order, and there is a
>>> circular dependency between A and B, he says to just make a dummy
>>> proxy object for B to pass into A, initialize A, and then initialize
>>> B.
>>> That also reminds me that a good use case for catchalls is making
>>> module-like objects.  I haven't seen any discussions of the 2 together
>>> but it's definitely worth thinking about how they interact.
>>> Andy
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at

More information about the es-discuss mailing list