Module system strawpersons

Kam Kasravi kamkasravi at yahoo.com
Sat Jan 16 10:49:03 PST 2010


Ihab, Mark:

Thanks for responding to the regex question. I am still befuddled by the relationships between module id's, namespaces, server resources and package management. Would you be able to provide commentary on the following example?
Given import './a/b/c', it looks like this is an implicit mapping to the URI ./a/b/c.js. (true/false). Within this module it's namespace may be appended to by adding attibutes to 'this' or setting attributes on the function. (true/false).Once this module returns there is a module with id 'a.b.c', there may or may not be a namespace that includes a.b.c.(true/false). If this module with id 'a.b.c' wanted to reference a module instance with id 'a.b' it could not do so directly but would need to do an (import 'a/b')(...). (true/false). Presumably the developer would need to know the arguments needed and whether the module function was intended to be an object. (true/false) Assuming module with id 'a.b.c.d' wanted to share the same module instance 'a.b' it would also do a similar import. (true/false) Given the common use case today of accessing a library framework by it's global instance, the import construct would need to be used or the instance would need
 to be provided as a free variable to the module function (true/false)

The motivation for the questions above is to understand how existing common use cases would change

Thx
Kam


On Jan 16, 2010, at 8:03 AM, Mark Miller <erights at gmail.com> wrote:

On Sat, Jan 16, 2010 at 12:10 AM, Kam Kasravi <kamkasravi at yahoo.com> wrote:
I'm sorry Mike, the network viewpoint is not what I meant, my bad.
Rather, at what point does the interpreter evaluate multiple import's.
I think Es4 suggested that eager fetching should be done
if 'use strict' were specified. This is one way to answer your argument below 
of modules_emaker_style vs defineDelayedFunction.
We are both asking the same question: how much static analysis 
is done and when. 

Btw, someone will ask at some point if import literal's or expressions 
should accommodate regex's. A different topic, but worth clarifying.


They should not. I still believe they should only be strings. But I can live with the proposed notion that they can be a JSON literal (i.e., an ES expression in the subset of ES corresponding to JSON). I think this is already more flexibility than we need in that position. I see no reason to go any farther.

 
thx
Kam



From: Mike Samuel <mikesamuel at gmail.com>
To: Kam Kasravi <kamkasravi at yahoo.com>
Cc: kkasravi <kkasravi at me.com>; es-discuss <es-discuss at mozilla.org>
Sent: Fri, January 15, 2010 7:33:24 PM

Subject: Re: Module system strawpersons

2010/1/15 Mike Samuel <mikesamuel at gmail.com>:
> 2010/1/15 Kam Kasravi <kamkasravi at yahoo.com>:
>> I guess the problem with examples is their analysis may not surface a particular use case. I agree at runtime this example may allow the interpreter to not over import.
>> The original question about how an interpreter may be
>> non-deterministic is whether the rules that determine whether the interpreter is lazy or eager have not been defined yet. The example was an attempt on my part to
>> have the developer drive how aggressive the interpreter is in prefetching resources. To summarize, there should be some rules that make each vendors interpreter behave like the next one, and there should be a way for the developer to make the interpreter prefetch even if the interpreter sees no reason to do so.
>
> I think determinism at the network level is out of scope of a module
> system, and may be out of scope of the Ecmascript group.
>
> Even ignoring network conditions, browsers' wildly different behavior
> around deferred scripts, the particulars of request headers, ordering
> of scripts, number of simultaneous open connections per host; can all
> affect the order in which requests are issued.
> Anything that requires deterministic behavior as apparent to a network
> observer seems like a non-starter to me.
>
> If you want a clear description of which resources are and are not
> fetched, then that's probably specifiable, but GET requests are
> supposed to be idempotent, so I don't know what that would gain
> assuming fetches are via GET.

Actually, I'm dumb.  idempotence only holds for # of requests >= 1.
Obviously, requesting the first time may convey significant
information.

> Java gets around restrictive definitions on class loading by
> separating the loading phase from the initialization phase.  Loading
> can involve network requests, and can be optimistic.  Initialization
> happens at well-defined times.  Would such a split satisfy the use
> cases you have in mind?
>
>> On Jan 15, 2010, at 4:11 PM, Mike Samuel <mikesamuel at gmail.com> wrote:
>>
>> 2010/1/15 Kam Kasravi <kamkasravi at yahoo.com>:
>> comments below...
>> ________________________________
>> From: Mike Samuel <mikesamuel at gmail.com>
>> To: Kam Kasravi <kamkasravi at yahoo.com>
>> Cc: kkasravi <kkasravi at me.com>; es-discuss <es-discuss at mozilla.org>
>> Sent: Fri, January 15, 2010 1:45:52 PM
>> Subject: Re: Module system strawpersons
>>
>> 2010/1/15 Kam Kasravi <kamkasravi at yahoo.com>:
>> Ihab, Mike - Thanks for the comments.
>> Yes, my examples confused definition with declaration, thanks for the
>> corrections.
>> I think I still have some unanswered questions which I'll try and clarify
>> as:
>> 1. I'm still not clear what the module identifier represents.
>>    Something like 'a/b/c' could be a URI or associated with a URI.
>>    Commonjs implicitly adds a '.js' which suggests this maps to a REST
>> construct.
>>    I think it would be helpful to clarify the above literal, the
>> module.id,
>>    any relation to javascript namespace and a mapping to server resources
>> since there is
>>    such an overlap with package management.
>>
>> 2. If the eagerness of the interpreter is determined by its implementation
>>    we could have lots of indeterminism across interpreters. There should
>>
>> Which sources of indeterminism do you foresee?
>> Is this indeterminism as apparent to a network observer or as apparent
>> to code running in the same interpreter?
>> [Kam] the network observer. A given interpreter may end up making lots of
>> fetches
>> or a few depending when it decided to resolve the import's.
>>
>>    probably be another construct that defines when resources are fetched.
>>    I'm not sure if the interpreter shouldn't be influenced by the
>> developer.
>>
>> Could you rephrase this last sentence, please?
>> [Kam]  as an example. lets say a module contains 3 adapters:
>> one that uses jQuery, one that uses Ext and one that uses YUI.
>> A eager interpreter may fetch all three when evaluating the module.
>> Yet if the choice of what framework to use (jQuery, Ext or YUI) was
>> determined by the developer/user early on, then the interpreter would
>> fetch 2 frameworks without needing to. If the developer had a
>> way to indicating to the interpreter that 2 of the frameworks weren't
>> needed then the behavior of the interpreter would be predictable.
>>
>> If the module needs all 3, then it needs to fetch all 3.
>>
>> But if only one adapter is needed, then there is presumably some code
>> somewhere which chooses which adapter.  Let's call it the
>> bootstrapper.  Then the module relationship looks like:
>>
>>   bootstrapper imports YUI-adapter
>>   YUI adapter imports YUI
>>   bootstrapper passes adapter to framework as a module parameter
>>
>> Since modules are first class, and are parameterizable, dependencies
>> can be injected without requiring over-import.
>> By not importing the adapters that are not needed, the other libraries
>> are not imported.
>>
>>
>>
>>
>> Brendan, do you recall es4 where the concept of a unit was introduced?
>> There was also some discussion where management and security
>> where implicitly mapped to the '.' between identifier parts. I cannot find
>> that reference.
>> Kam
>>
>> ________________________________
>> From: Mike Samuel <mikesamuel at gmail.com>
>> To: kkasravi <kkasravi at me.com>
>> Cc: es-discuss <es-discuss at mozilla.org>
>> Sent: Fri, January 15, 2010 11:20:48 AM
>> Subject: Re: Module system strawpersons
>>
>> 2010/1/15 kkasravi <kkasravi at me.com>:
>> Hi Mike, Ihab:
>>
>> One factor that would influence eager or lazy fetching is where the
>> import keyword may appear within the ecmascript grammar.
>>
>> The proposal suggests it could appear anywhere
>> an identifier could appear. For example:
>>
>> I believe it cannot appear where a LeftHandSideExpression is expected
>> because a function cannot be assigned to.
>> So no replacing
>>  foo.bar = baz
>> with
>>  (import ...) = baz
>>
>> 1)  function find(name) {
>>      var name = foo.bar.Baz.find(name); // identifier 'foo.bar.Baz'
>>       ...
>>    }
>>
>> Replacing foo.bar with import would yield
>>
>> 2) function find(name) {
>>     var name = (import 'foo/bar').Baz.find(name);
>>
>> Provisioning is separate from importing.  The above is looking up Baz
>> on a function instance which normally would be the same as
>>  var name = Function.prototype.Baz.find(name)
>>
>> I think normal usage would look like
>>    var name = (import ...)(module, instance, parameters).Baz.find(name)
>>
>>     ...
>>   }
>>
>> Replacing foo.bar.Baz with import would yield
>>
>> 3) function find(name) {
>>     var name = (import 'foo/bar/Baz').find(name);
>>     ...
>>   }
>>
>> I provided 2) and 3) because its not clear where a module definition
>> begins.
>> The presumption by naming convention is that foo.bar.Baz can be found
>> within
>> a relative resource named ./foo/bar.js on some server. This metadata
>> needs
>> to
>> be somehow made available to the javascript runtime. So in some ways
>> module's need package info. Let's assume the correct one is 2).
>>
>> Looking at 2), current javascript behavior is always lazy fetching
>> because
>> the above function find
>>
>> fetching can be eager, but evaluation happens whenever the ImportExpr
>> is reached, possibly not at all.
>>
>> may not be called immediately or not at all.  The javascript runtime
>> would
>> not complain about
>> identifiers that are not immediately accessed or not accessed at all.
>>
>> Doing eager fetching means that we would need to fetch all imports prior
>> to eval.
>> Impacts are:
>> 1. We fetch more than necessary and immediately. User perception is the
>> new js runtime is much slower.
>>
>> Eager fetching can be done, or can be delayed, or multiple module
>> definitions could be fetched in the same transaction.  The degree of
>> eagerness is up to the interpreter.
>>
>> 2. We forces all import expressions to be statically defined.
>>
>> Summary:
>> If import can appear in place of an identifier, there is no choice but to
>> do lazy fetching. Lazy fetching without CPS (continuation passing style)
>> support means you could not do (import foo/bar').Baz.find(name);
>>
>>
>> Kam
>>
>>
>>
>> On Jan 14, 2010, at 2:29 PM, Mike Samuel wrote:
>>
>> Ok, so let me try to make sure I understand the special form in
>> strawman:modules_emaker_style, by defining a mini-strawman and
>> knocking it down.
>>
>> Consider a special form
>>  (f, definer) = defineDelayedFunction();
>> where f is a function that will block on first call until definer has
>> been called with an arguments array and a function body upon which
>> point it will behave as if it were defined via new Function(...) with
>> those arguments and function body.  definer raises an Error on second
>> and subsequent calls.
>>
>> defineDelayedFunction could be used with an async channel like
>> XMLHttpRequest to define a module system, but all module definitions
>> would happen at execute time, so it cannot be used to define a module
>> system that resolves definitions prior to body evaluation.
>>
>> In modules_emaker_style, imports are statically determinable, so the
>> set of dependencies is fully satisfied before the Program is
>> evaluated, and this can be done recursively to make full use of
>> sockets.  A browser could optimistically find import definitions and
>> start downloading before the full script body is loaded.
>>
>> defineDelayedFunction would impose lazy fetching, but
>> modules_emaker_style allows eager fetching.
>>
>>
>> 2010/1/14  <ihab.awad at gmail.com>:
>> Hi Mike,
>>
>> On Thu, Jan 14, 2010 at 1:29 PM, Mike Samuel <mikesamuel at gmail.com>
>> wrote:
>> Are these proposals mutually exclusive or complementary.
>> If (1) and (2) are exclusive, is there a place to collect use cases
>> for a module-off?
>>
>> For my part, I think (1) and (2) are counterproposals, but there may
>> exist a bunch of cross-pollination. For example, I will probably end
>> up stealing Kris's "import with" syntax sometime.
>>
>> I don't see the word module anywhere in the packages proposal besides
>> footnotes.
>> What is the relationship between packages and modules.
>>
>> The packages proposal was written with module proposal (1) in mind,
>> but is compatible in the broad sense with either. It does say in the
>> beginning that it "... is intended to satisfy the Uniform location and
>> retrieval goal of modules_emaker_style". There are more details under
>> "Use in import" (where I just updated the syntax a little bit).
>>
>> 2.
>> http://wiki.ecmascript.org/doku.php?id=strawman:modules_emaker_style
>>
>>     Module proposal, by Ihab, focusing on EMaker-style invocation
>> semantics.
>>
>> "First class objects. To the extent possible, module system components
>> must be represented as first-class ECMAScript objects."
>> Does object exclude primitives such as strings, or is the goal to
>> exclude abstractions like LexicalScopes and References?
>>
>> The point is that module system components are made to appear, to the
>> extent possible, as first-class objects rather than unmentionable
>> "static" magic. E.g., contrast Java where, if Foo is a class, the
>> expression "Foo" by itself is not an object; generic class parameters
>> are not objects; etc. -- which makes higher-order programming somewhat
>> harder.
>>
>> "import" is added to the reserved keyword list?
>>
>> It should be reserved now, and is for sure reserved according to this
>> proposal.
>>
>> "return {
>>  getX: function() { return x; },
>>  getY: function() { return y; },"
>> indentation
>>
>> Fixed, tx.
>>
>> "In the module’s code, this is initialized to a new object that is
>> instanceof the module function"
>> Does this mean that access to a module instance conveys authority to
>> create new module instances?
>>
>> Yes. Just like any other ES function where it's return value is
>> instanceof that function.
>>
>> "An import expression evaluates immediately to a module function
>> despite the fact that the specified module may have been fetched by
>> asynchronous means (e.g., nonblocking network operations). This is
>> done by taking advantage of the fact that import is a special form."
>> Does this require "import" to be a special form instead of a
>> desugaring?  Or can the special form be boiled down to a function
>> which when called, delays until another function is invoked,
>> presumably with a valid FunctionExpr string as its sole argument?
>>
>> Would that require a continuation-passing transform of the code after
>> the desugared "import"? If so, that may not be semantics preserving.
>>
>> Ihab
>>
>> --
>> Ihab A.B. Awad, Palo Alto, CA
>>
>>
>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>>
>>
>

_______________________________________________
es-discuss mailing list
es-discuss at mozilla.org
https://mail.mozilla.org/listinfo/es-discuss




-- 
Text by me above is hereby placed in the public domain

   Cheers,
   --MarkM

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20100116/605fceba/attachment-0001.html>


More information about the es-discuss mailing list