Written Proposal for "package" Keyword for ES20XX Imports
Greg McLeod
cleod9 at gmail.com
Tue Feb 21 22:53:52 UTC 2017
@Logan
Yes that's correct more or less. This is demonstrated with the
`module.injects` concept showcased in the Gist. Any inheritance that occurs
at the top of level of a module can be statically detected by parsing the
AST for `extends` within that scope. Keywords found after an `extends`
could be given execution priority so that they are imported inline
immediately. All other exported class declarations that don't have an
`extends` can be deferred via the injection mechanism shown in the example
code.
In the case of dynamic extension with `extends doThing(A)`, both `doThing`
and `A` would need to treated with priority. Though I imagine for a first
iteration of something like this there could be a restriction on that type
of syntax while those details are fleshed out to keep things maximally
minimal.
On Tue, Feb 21, 2017 at 3:59 PM, Logan Smyth <loganfsmyth at gmail.com> wrote:
> Fair enough. Is the idea that class declarations would be lazy-initialized
> somehow then? It seems like the runtime behavior of class declarations
> would make things difficult. What is responsible for knowing that the class
> `A` needs to be initialized before `class B extends A {}`? What if the
> declaration is using runtime behavior like `class B extends doThing(A) {}`?
>
>
>
> On Tue, Feb 21, 2017 at 11:48 AM, Greg McLeod <cleod9 at gmail.com> wrote:
>
>> @Logan: Oh I see what you mean, I suppose I was thinking about it in a
>> different way. I do know in ES6 the import keywords are always hoisted to
>> the top, so it should be a given that the modules will be "resolved"
>> already as a consequence of that. But there is no guarantee that all of the
>> modules are linked successfully, namely in the edge cases of inheritance.
>>
>> Consider the following
>>
>> ```js
>> // app.js
>> import A from "./a.js";
>> import B from "./b.js";
>>
>> var a = new A();
>> var b = new B();
>>
>> // a.js
>> import B from "./b.js";
>>
>> console.log("A's reference to B", B);
>>
>> export default class A {
>> constructor() {
>> }
>> }
>>
>> // b.js
>> import A from "./a.js";
>>
>> console.log("B's reference to A", A);
>>
>> export default class B extends A {
>> constructor() {
>> super();
>> }
>> }
>> ```
>>
>> In the latest Babel the above code fails to run on the first line of
>> app.js (at the time it attempts to execute `_inherits(B, _A);`.). This is
>> because "A" is undefined in module b.js due to the circular dependency. In
>> this case Babel basically executed code in the incorrect order for this to
>> be able to work. The package keyword avoids this by creating a hoist-like
>> behavior for classes that are inherited, which is safe to do given the
>> proposed limitations in the top-level scope
>>
>> I should note that circular dependencies like this are (hopefully) not
>> too common, but one coming from another language might expect this to work
>> based on how ES6 imports are described. I think the behavior of the package
>> keyword could be much more transparent about what it's capable of.
>>
>>
>>
>> On Tue, Feb 21, 2017 at 1:56 PM, Logan Smyth <loganfsmyth at gmail.com>
>> wrote:
>>
>>> I don't have tons of comments on the proposal as a whole, but I do think
>>> there may be confusion about ES6 imports. Imports are resolved and
>>> processed and modules linked before any execution of the module body takes
>>> place. I can't tell from your description if you are reading that
>>> differently.
>>>
>>> On Tue, Feb 21, 2017 at 10:48 AM, Greg McLeod <cleod9 at gmail.com> wrote:
>>>
>>>> Thanks Ryan. I think there would be a bit of an issue with introducing
>>>> dictionary support alone in that it does not provide a new way for the
>>>> language to define where modules actually live in the application itself as
>>>> opposed to the file system. This misses out on the benefits the package
>>>> keyword could provide. "package" should impose some limitations on the
>>>> top-most scope of a module to facilitate the ability to define the packages
>>>> before actually executing a module's body.
>>>>
>>>> To elaborate, one of the biggest benefits I'd like to emphasize is the
>>>> complete isolation of dependency resolution and actual module body
>>>> execution.
>>>>
>>>> The package keyword in my proposal would allow you to arbitrarily say
>>>> "here's the complete structure of my app, all dependencies already
>>>> resolved" and subsequently take action on it after it has been fully loaded
>>>> into memory in its entirety. Augmenting existing import syntax cannot allow
>>>> this since the core body of each module is being executed amidst the
>>>> dependency graph being resolved as each "import" is encountered by the
>>>> interpreter.
>>>>
>>>>
>>>> On Tue, Feb 21, 2017 at 12:52 PM, Ryan Birmingham <
>>>> rainventions at gmail.com> wrote:
>>>>
>>>>> I like the idea you're working from here, it seems to partially
>>>>> resemble header files. I'm not sure if a package keyword is needed though;
>>>>> couldn't you accomplish the same thing with just adding dictionary support
>>>>> and an optional alias parameter to import/export?
>>>>>
>>>>> -Ryan Birmingham
>>>>>
>>>>> On 21 February 2017 at 12:27, Greg McLeod <cleod9 at gmail.com> wrote:
>>>>>
>>>>>> Hi all,
>>>>>>
>>>>>> Back in 2015 I was working on a proposal for the "package" keyword,
>>>>>> but stopped prematurely as ES6/ES2015 had already been shipped. Since then
>>>>>> I've been occasionally iterating on it anyway in order to flesh out my
>>>>>> ideas with how it could fit with the new import syntax. I wanted to share
>>>>>> with the mailing list to get some feedback on it, as well as help
>>>>>> facilitate some of the discussion regarding future import syntax.
>>>>>>
>>>>>> Proposal can be found here:
>>>>>> https://gist.github.com/Cleod9/7f73017905d124210ec8
>>>>>>
>>>>>> I should note that a lot of this is derived from an ActionScript to
>>>>>> JavaScript proof-of-concept transpiler I wrote a few years back. (Live
>>>>>> demo: https://as3js.org/demo/ ). I believe this type of package
>>>>>> syntax/behavior has already been possible since ES5, although I have yet to
>>>>>> find any proposals for the keyword that resemble that of battle-tested
>>>>>> languages like Java/C#.
>>>>>>
>>>>>> I think there are a lot of time-saving qualities that packages could
>>>>>> provide for bundled JS applications we have yet to explore, and it could
>>>>>> even open the door to a JS standard library. Even if this doesn't go
>>>>>> anywhere I certainly hope by making this proposal public it will be a
>>>>>> useful for reference for what is possible in the current state of affairs.
>>>>>>
>>>>>> Any feedback would be greatly appreciated!
>>>>>>
>>>>>> Greg
>>>>>>
>>>>>> P.S. Screen-cap of a potential IDE future with packages:
>>>>>> http://i.imgur.com/D5EGNUN.gifv
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> 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
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20170221/5328d7a6/attachment-0001.html>
More information about the es-discuss
mailing list