Minor questions on new module BNF

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Minor questions on new module BNF

Domenic Denicola-2
Sam was saying that http://wiki.ecmascript.org/doku.php?id=harmony:modules is up to date. If so, I'm seeing a few things missing from the BNF. It would be great to get these clarified so people can start writing accurate transpilers.

1. It looks like `ExportDeclaration` can only occur inside `ModuleBody`, which itself can only occur as part of the named `ModuleDeclaration` production. I thought we would be able to export things without explicit named module declaration, so shouldn't `ExportDeclaration` be added to `ScriptElement`? Or perhaps to `Statement`? At http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples the "compiler/Lexer.js" example contains such a situation, which seems invalid from the current grammar.

2. Is there any way to simply "execute" a module that does not export anything? This is a common technique in both client and server-side JavaScript today, e.g.

```js
// initSubsystem1.js
console.log("initializing subsystem 1...");

// initSubsystem2.js
console.log("initializing subsystem 2...");

// init.js
require("./initSubsystem1");
require("./initSubsystem2");
```

On the client side this is common for e.g. plugins:

```js
var Backbone = require("backbone");
require("backbone.layoutmanager");

// now `Backbone` has been augmented with a `Backbone.LayoutView` property we can use.
```

I don't see any way to do this, except perhaps via

```js
import defaultExportWillBeUndefinedSoThisBindingIsPointless from "./initSubsystem1";
import thisOneTooOhMyPoorScopeIsBeingPolluted from "./initSubsystem2";
```

A production of the form `"import" ModuleSpecifier ";"` would probably help this.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Minor questions on new module BNF

Domenic Denicola-2
> so shouldn't `ExportDeclaration` be added to `ScriptElement`? Or perhaps to `Statement`?

Upon reflection, `Statement` is obviously incorrect, as it prevents static determination of a module's exports. `ScriptElement` still seems good though.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Sam Tobin-Hochstadt
In reply to this post by Domenic Denicola-2
On Sun, Jun 2, 2013 at 11:59 PM, Domenic Denicola
<[hidden email]> wrote:
> Sam was saying that http://wiki.ecmascript.org/doku.php?id=harmony:modules is up to date. If so, I'm seeing a few things missing from the BNF. It would be great to get these clarified so people can start writing accurate transpilers.
>
> 1. It looks like `ExportDeclaration` can only occur inside `ModuleBody`, which itself can only occur as part of the named `ModuleDeclaration` production. I thought we would be able to export things without explicit named module declaration, so shouldn't `ExportDeclaration` be added to `ScriptElement`? Or perhaps to `Statement`? At http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples the "compiler/Lexer.js" example contains such a situation, which seems invalid from the current grammar.

The idea here is that modules will typically be written in files like
"compiler/Lexer.js", where the starting grammar production *is*
`ModuleBody`.

>
> 2. Is there any way to simply "execute" a module that does not export anything? This is a common technique in both client and server-side JavaScript today, e.g.

I would just write `import {} from "someModule";`

Sam
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Minor questions on new module BNF

Domenic Denicola-2
From: [hidden email] [mailto:[hidden email]] On Behalf Of Sam Tobin-Hochstadt

> The idea here is that modules will typically be written in files like "compiler/Lexer.js", where the starting grammar production *is* `ModuleBody`.

Ah, that makes sense! It's a nice way of prohibiting `<script>export function foo() { }</script>` as well, assuming inline `<script>` corresponds to `Script`. It would be helpful to update the wiki with this, or more generally to show how this grammar will integrate with the rest of the grammar.

> I would just write `import {} from "someModule";`

That appears to be disallowed; I believe

    "{" ImportSpecifier ("," ImportSpecifier)* ","? "}"

requires at least one `ImportSpecifier`. (It's also sad and ugly; any reason not to allow `import "someModule";`?)
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Yehuda Katz
On Mon, Jun 3, 2013 at 12:24 AM, Domenic Denicola <[hidden email]> wrote:
From: [hidden email] [mailto:[hidden email]] On Behalf Of Sam Tobin-Hochstadt

> The idea here is that modules will typically be written in files like "compiler/Lexer.js", where the starting grammar production *is* `ModuleBody`.

Ah, that makes sense! It's a nice way of prohibiting `<script>export function foo() { }</script>` as well, assuming inline `<script>` corresponds to `Script`. It would be helpful to update the wiki with this, or more generally to show how this grammar will integrate with the rest of the grammar.

> I would just write `import {} from "someModule";`

That appears to be disallowed; I believe

    "{" ImportSpecifier ("," ImportSpecifier)* ","? "}"

requires at least one `ImportSpecifier`. (It's also sad and ugly; any reason not to allow `import "someModule";`?)

I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.
 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Brendan Eich-3
Yehuda Katz wrote:
> I've advocated for this in the past. I believe it should be allowed.
>
> Separately, I would like this form to be specified as deferring
> execution until bindings are explicitly imported (from another
> module), or a synchronous `System.get` call is made.
>
> This would make it possible to guarantee that a synchronous
> `System.get` will succeed, without being forced to execute the module
> first.

+1.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Jeff Morrison
In reply to this post by Yehuda Katz
Big +1 on being able to defer execution until explicit import. It definitely seems useful to allow for control over dependency specifications separately from [potential] dependency execution. More concretely, I don't think you could do something like the following with the current module spec (correct if wrong):

exports.foo = function() {
  var bar = require('bar');
  bar.baz();
}

What about specifying some form of hoisting for ImportDeclarations so that dependencies for a module can be declared separately from their execution? This would still allow for compile-time resolution and linking while also addressing concerns about runtime-conditional dependencies...

-Jeff

On 6/3/13 9:33 AM, Yehuda Katz wrote:
On Mon, Jun 3, 2013 at 12:24 AM, Domenic Denicola <[hidden email]> wrote:
From: [hidden email] [mailto:[hidden email]] On Behalf Of Sam Tobin-Hochstadt

> The idea here is that modules will typically be written in files like "compiler/Lexer.js", where the starting grammar production *is* `ModuleBody`.

Ah, that makes sense! It's a nice way of prohibiting `<script>export function foo() { }</script>` as well, assuming inline `<script>` corresponds to `Script`. It would be helpful to update the wiki with this, or more generally to show how this grammar will integrate with the rest of the grammar.

> I would just write `import {} from "someModule";`

That appears to be disallowed; I believe

    "{" ImportSpecifier ("," ImportSpecifier)* ","? "}"

requires at least one `ImportSpecifier`. (It's also sad and ugly; any reason not to allow `import "someModule";`?)

I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.
 
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Dave Herman
In reply to this post by Yehuda Katz
On Jun 3, 2013, at 9:33 AM, Yehuda Katz <[hidden email]> wrote:

> On Mon, Jun 3, 2013 at 12:24 AM, Domenic Denicola <[hidden email]> wrote:
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Sam Tobin-Hochstadt
>
> > I would just write `import {} from "someModule";`
>
> That appears to be disallowed; I believe
>
>     "{" ImportSpecifier ("," ImportSpecifier)* ","? "}"
>
> requires at least one `ImportSpecifier`.

Oversight. Fixed.

> (It's also sad and ugly; any reason not to allow `import "someModule";`?)
>
> I've advocated for this in the past. I believe it should be allowed.

I've always liked this too, and just hadn't really gotten to it. But I've added it to the wiki page too. I'll work with Jason to add this to the reference library; it should be a small addition.

> Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.
>
> This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

Yep, agreed. (To be pedantic, it's not that it defers execution so much as that it doesn't force execution.)

Dave

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Dave Herman
In reply to this post by Domenic Denicola-2
On Jun 3, 2013, at 12:24 AM, Domenic Denicola <[hidden email]> wrote:

> Ah, that makes sense! It's a nice way of prohibiting `<script>export function foo() { }</script>` as well, assuming inline `<script>` corresponds to `Script`. It would be helpful to update the wiki with this, or more generally to show how this grammar will integrate with the rest of the grammar.

I added a note at the end of the grammar section. Do you think that helps make it a little clearer?

Thanks,
Dave

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Kevin Smith
In reply to this post by Dave Herman


Yep, agreed. (To be pedantic, it's not that it defers execution so much as that it doesn't force execution.)

Can you explain?  I would naively expect for this:

    // someModule
    console.log("someModule");

    // main
    import "someModule";
    console.log("main");

when executing main, to output:

    > someModule
    > main

Thanks!

{ Kevin }


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Kevin Smith
In reply to this post by Dave Herman

> That appears to be disallowed; I believe
>
>     "{" ImportSpecifier ("," ImportSpecifier)* ","? "}"
>
> requires at least one `ImportSpecifier`.

Oversight. Fixed.


Looks good, but I'm thinking that this should probably _not_ be allowed:

    import {,} from "x";

{ Kevin }


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Yehuda Katz
In reply to this post by Kevin Smith
On Tue, Jun 4, 2013 at 6:29 AM, Kevin Smith <[hidden email]> wrote:


Yep, agreed. (To be pedantic, it's not that it defers execution so much as that it doesn't force execution.)

Can you explain?  I would naively expect for this:

    // someModule
    console.log("someModule");

    // main
    import "someModule";
    console.log("main");

when executing main, to output:

    > someModule
    > main

In general, expectations about side-effects that happen during module loading are really edge-cases. I would go as far as to say that modules that produce side effects during initial execution are "doing it wrong", and are likely to produce sadness.

In this case, the `import` statement is just asking the module loader to download "someModule", but allowing the app to move on with life and not bother executing it. This would allow an app to depend on a bunch of top-level modules that got executed only once the user entered a particular area, saving on initial boot time.
 

Thanks!

{ Kevin }



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Minor questions on new module BNF

Domenic Denicola-2
From: Yehuda Katz [[hidden email]]

> In general, expectations about side-effects that happen during module loading are really edge-cases. I would go as far as to say that modules that produce side effects during initial execution are "doing it wrong", and are likely to produce sadness.

> In this case, the `import` statement is just asking the module loader to download "someModule", but allowing the app to move on with life and not bother executing it. This would allow an app to depend on a bunch of top-level modules that got executed only once the user entered a particular area, saving on initial boot time.
 
I don't think this is correct. It is strongly counter to current practice, at the very least, and I offered some examples up-thread which I thought were pretty compelling in showing how such side-effecting code is fairly widely used today.

This isn't a terribly important thing, to be sure. But IMO it will be very surprising if

```js
import x from "x";
```

executes the module "x", producing side effects, but

```js
import "x";
```

does not. It's surprising precisely because it's in that second case that side effects are desired, whereas I'd agree that for modules whose purpose is to export things producing side effects is "doing it wrong."






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Kevin Smith
In reply to this post by Yehuda Katz


In this case, the `import` statement is just asking the module loader to download "someModule", but allowing the app to move on with life and not bother executing it. This would allow an app to depend on a bunch of top-level modules that got executed only once the user entered a particular area, saving on initial boot time.
 

That explains it, but I wonder how much time is saved.  The browser would have to fetch the module and parse the module text in order to pick up dependencies.  If modules don't have side-effects, then I presume that they don't really do much of anything when executed, other than initialize bindings.

Thanks again!

{ Kevin }


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Jason Orendorff
In reply to this post by Yehuda Katz
On Mon, Jun 3, 2013 at 11:33 AM, Yehuda Katz <[hidden email]> wrote:
I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

It makes the static import language a bit more expressive, but why is it necessary?

For performance? The alternative, if a module has expensive initialization, would be to have it initialize itself more lazily.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

It would definitely make that possible, but what `System.get()` use case are you looking to support? To my mind `System.get()` is like examining `$LOADED_FEATURES` in Ruby or `sys.modules` in Python; those use cases exist, but the kind of code you're writing when you touch those is typically either an egregious hack or it's generic across all modules, right? They don't need or merit syntactic support.

I want to understand the motivation, because Domenic asked for syntax that just loads and runs a module, without bindings. It seems like we could support that feature with a tweak of the grammar, but you're proposing taking that exact syntax and using it for something else. I expect people trying to load and run a module will greatly outnumber people trying to load and *not* run a module.  Wouldn't we be astonishing more people by doing it your way?

-j


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Yehuda Katz
On Tue, Jun 4, 2013 at 8:11 AM, Jason Orendorff <[hidden email]> wrote:
On Mon, Jun 3, 2013 at 11:33 AM, Yehuda Katz <[hidden email]> wrote:
I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

It makes the static import language a bit more expressive, but why is it necessary?

For performance? The alternative, if a module has expensive initialization, would be to have it initialize itself more lazily.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

It would definitely make that possible, but what `System.get()` use case are you looking to support? To my mind `System.get()` is like examining `$LOADED_FEATURES` in Ruby or `sys.modules` in Python; those use cases exist, but the kind of code you're writing when you touch those is typically either an egregious hack or it's generic across all modules, right? They don't need or merit syntactic support.

I want to understand the motivation, because Domenic asked for syntax that just loads and runs a module, without bindings. It seems like we could support that feature with a tweak of the grammar, but you're proposing taking that exact syntax and using it for something else. I expect people trying to load and run a module will greatly outnumber people trying to load and *not* run a module.  Wouldn't we be astonishing more people by doing it your way?

I'm happy to give in here, but I'm nervous about how strongly Domenic wants to connect the timing of imports with execution in people's minds.

If people actually write code like that, it's going to be a bad time.
 


-j



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Роман



2013/6/4 Yehuda Katz <[hidden email]>
On Tue, Jun 4, 2013 at 8:11 AM, Jason Orendorff <[hidden email]> wrote:
On Mon, Jun 3, 2013 at 11:33 AM, Yehuda Katz <[hidden email]> wrote:
I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

It makes the static import language a bit more expressive, but why is it necessary?

For performance? The alternative, if a module has expensive initialization, would be to have it initialize itself more lazily.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

It would definitely make that possible, but what `System.get()` use case are you looking to support? To my mind `System.get()` is like examining `$LOADED_FEATURES` in Ruby or `sys.modules` in Python; those use cases exist, but the kind of code you're writing when you touch those is typically either an egregious hack or it's generic across all modules, right? They don't need or merit syntactic support.

I want to understand the motivation, because Domenic asked for syntax that just loads and runs a module, without bindings. It seems like we could support that feature with a tweak of the grammar, but you're proposing taking that exact syntax and using it for something else. I expect people trying to load and run a module will greatly outnumber people trying to load and *not* run a module.  Wouldn't we be astonishing more people by doing it your way?

I'm happy to give in here, but I'm nervous about how strongly Domenic wants to connect the timing of imports with execution in people's minds.

If people actually write code like that, it's going to be a bad time.
 


-j



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
С уважением, Роман

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Rick Waldron
In reply to this post by Yehuda Katz


On Tuesday, June 4, 2013, Yehuda Katz wrote:
On Tue, Jun 4, 2013 at 8:11 AM, Jason Orendorff <<a href="javascript:_e({}, &#39;cvml&#39;, &#39;jason.orendorff@gmail.com&#39;);" target="_blank">jason.orendorff@...> wrote:
On Mon, Jun 3, 2013 at 11:33 AM, Yehuda Katz <<a href="javascript:_e({}, &#39;cvml&#39;, &#39;wycats@gmail.com&#39;);" target="_blank">wycats@...> wrote:
I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

It makes the static import language a bit more expressive, but why is it necessary?

For performance? The alternative, if a module has expensive initialization, would be to have it initialize itself more lazily.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

It would definitely make that possible, but what `System.get()` use case are you looking to support? To my mind `System.get()` is like examining `$LOADED_FEATURES` in Ruby or `sys.modules` in Python; those use cases exist, but the kind of code you're writing when you touch those is typically either an egregious hack or it's generic across all modules, right? They don't need or merit syntactic support.

I want to understand the motivation, because Domenic asked for syntax that just loads and runs a module, without bindings. It seems like we could support that feature with a tweak of the grammar, but you're proposing taking that exact syntax and using it for something else. I expect people trying to load and run a module will greatly outnumber people trying to load and *not* run a module.  Wouldn't we be astonishing more people by doing it your way?

I'm happy to give in here, but I'm nervous about how strongly Domenic wants to connect the timing of imports with execution in people's minds.

If people actually write code like that, it's going to be a bad time.


This is possibly a faux pas, but what you just wrote reminded me of php's include behavior—which is a very bad time.


Rick


 


-j



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Dave Herman
In reply to this post by Kevin Smith
On Jun 4, 2013, at 6:31 AM, Kevin Smith <[hidden email]> wrote:

> Looks good, but I'm thinking that this should probably _not_ be allowed:
>
>     import {,} from "x";

Right you are! Fixed, thanks.

Dave

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Minor questions on new module BNF

Jeff Morrison
In reply to this post by Jason Orendorff
I still kinda like the idea of allowing ImportDeclarations to be expressed anywhere inside a ScriptElement (including in its children), and then hoisting the declaration for compilation/linking, but only executing the dependency when the statement is reached at runtime. It is then a parse error if an ImportDeclaration is outside of a ScriptElement context.

The System.get() paradigm is kind of awkward and indistinguishable from the import syntax in terms of its expressive relation.
If its all we can get, so be it -- but it feels pretty unpolished.

-Jeff

On 6/4/13 8:11 AM, Jason Orendorff wrote:
On Mon, Jun 3, 2013 at 11:33 AM, Yehuda Katz <[hidden email]> wrote:
I've advocated for this in the past. I believe it should be allowed.

Separately, I would like this form to be specified as deferring execution until bindings are explicitly imported (from another module), or a synchronous `System.get` call is made.

It makes the static import language a bit more expressive, but why is it necessary?

For performance? The alternative, if a module has expensive initialization, would be to have it initialize itself more lazily.

This would make it possible to guarantee that a synchronous `System.get` will succeed, without being forced to execute the module first.

It would definitely make that possible, but what `System.get()` use case are you looking to support? To my mind `System.get()` is like examining `$LOADED_FEATURES` in Ruby or `sys.modules` in Python; those use cases exist, but the kind of code you're writing when you touch those is typically either an egregious hack or it's generic across all modules, right? They don't need or merit syntactic support.

I want to understand the motivation, because Domenic asked for syntax that just loads and runs a module, without bindings. It seems like we could support that feature with a tweak of the grammar, but you're proposing taking that exact syntax and using it for something else. I expect people trying to load and run a module will greatly outnumber people trying to load and *not* run a module.  Wouldn't we be astonishing more people by doing it your way?

-j



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12