Standard modules - concept or concrete?

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

Standard modules - concept or concrete?

Brian Di Palma
The standard modules wiki page (
http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard ) is
not clear as to whether what it describes is a concrete proposal and
that ES6 will include it or it's purely a concept.

The page does not seem to be linked/mentioned from any of the other
module pages ( at least based on a cursory read of the main module
pages ).

Is this a prerequisite for static checks in modules ( forbid all
globals in modules unless explicitly imported )? I'm sure the checks
aren't as harsh, but I'd love such strictness as it can make tooling
more powerful and code simpler to understand and follow. The idea that
you can grab anything from the global object without first importing
it seems wrong.

Are standard modules the future of built-ins for ES?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Sat, Jun 8, 2013 at 5:08 AM, Brian Di Palma <[hidden email]> wrote:
> The standard modules wiki page (
> http://wiki.ecmascript.org/doku.php?id=harmony:modules_standard ) is
> not clear as to whether what it describes is a concrete proposal and
> that ES6 will include it or it's purely a concept.

ES6 will definitely provide some set of standard modules.  The primary
open questions are (a) what will the modules be named and (b) how
fine-grained will the module split be.

> Is this a prerequisite for static checks in modules ( forbid all
> globals in modules unless explicitly imported )? I'm sure the checks
> aren't as harsh, but I'd love such strictness as it can make tooling
> more powerful and code simpler to understand and follow. The idea that
> you can grab anything from the global object without first importing
> it seems wrong.

The global object will still be accessible in modules.  Of course, you
can create new module loaders with an empty global.

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

Re: Standard modules - concept or concrete?

Brian Di Palma
Good, I like the standard modules idea.

On Sat, Jun 8, 2013 at 2:33 PM, Sam Tobin-Hochstadt <[hidden email]> wrote:
>
> The global object will still be accessible in modules.  Of course, you
> can create new module loaders with an empty global.
>

Umm. It makes porting old code easier.

If we could guarantee that any reference inside a module had to have
an import definition I imagine IDEs and development concatenation
tools would provide
fast feedback when those rules are broken. Why would people use the
standard modules if they can just access the global?

Is it expected that developers import things like Date because it
would be good practice?

import { Date } from "@std";

or simply

new Date();

I can imagine many people just taking option 2. Seem to make standard
modules somewhat redundant, or at least it undermines them.
I suppose then the static checks are only to check that a module
imports the identifiers that another module exports, is that it?
If we can grab anything from the global that means un-imported
references can be used all over module code and the environment will
just have
to shrug its shoulders an accept it. No compile time error. Somewhat
disappointed with that.

So modules will be allowed to be polluted by the global state, not
just build in globals but any possible user defined global state.

The possibility of strengthening module consistency is off the table?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Sat, Jun 8, 2013 at 2:00 PM, Brian Di Palma <[hidden email]> wrote:

> Good, I like the standard modules idea.
>
> On Sat, Jun 8, 2013 at 2:33 PM, Sam Tobin-Hochstadt <[hidden email]> wrote:
>>
>> The global object will still be accessible in modules.  Of course, you
>> can create new module loaders with an empty global.
>>
>
> Umm. It makes porting old code easier.
>
> If we could guarantee that any reference inside a module had to have
> an import definition I imagine IDEs and development concatenation
> tools would provide
> fast feedback when those rules are broken. Why would people use the
> standard modules if they can just access the global?
>
> Is it expected that developers import things like Date because it
> would be good practice?
>
> import { Date } from "@std";
>
> or simply
>
> new Date();
>
> I can imagine many people just taking option 2. Seem to make standard
> modules somewhat redundant, or at least it undermines them.
> I suppose then the static checks are only to check that a module
> imports the identifiers that another module exports, is that it?
> If we can grab anything from the global that means un-imported
> references can be used all over module code and the environment will
> just have
> to shrug its shoulders an accept it. No compile time error. Somewhat
> disappointed with that.

I think you misunderstand.  The requirement that modules not have free
variables at compile time *includes* global references. I expect that
development environments won't have a problem handling this or
enforcing whatever properties you're looking for.

>
> So modules will be allowed to be polluted by the global state, not
> just build in globals but any possible user defined global state.
>
> The possibility of strengthening module consistency is off the table?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Brian Di Palma
On Sat, Jun 8, 2013 at 7:07 PM, Sam Tobin-Hochstadt <[hidden email]> wrote:
>
> I think you misunderstand.  The requirement that modules not have free
> variables at compile time *includes* global references. I expect that
> development environments won't have a problem handling this or
> enforcing whatever properties you're looking for.

I think I see what you're saying. Let me just see if I'm correct.

At compile time any references in a module which are not explicitly
imported but are language globals will not cause compile errors.
Any references which aren't explicitly imported and aren't language
globals will cause a compile error?

So

module "test" {
    new Date();
}

is fine.

While

module "test2" {
    $
}

will throw an error unless you add the line

import $ from "jquery";

even if jQuery was available in the global scope and had been loaded
in by a normal script tag?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Sat, Jun 8, 2013 at 2:30 PM, Brian Di Palma <[hidden email]> wrote:

> On Sat, Jun 8, 2013 at 7:07 PM, Sam Tobin-Hochstadt <[hidden email]> wrote:
>>
>> I think you misunderstand.  The requirement that modules not have free
>> variables at compile time *includes* global references. I expect that
>> development environments won't have a problem handling this or
>> enforcing whatever properties you're looking for.
>
> I think I see what you're saying. Let me just see if I'm correct.
>
> At compile time any references in a module which are not explicitly
> imported but are language globals will not cause compile errors.
> Any references which aren't explicitly imported and aren't language
> globals will cause a compile error?

This is close, but not quite right.  The rule is that any unbound
variables in modules are errors.  The variables may be bound by import
declarations, or by lexical bindings such as `var` or `let`, or by
bindings on the global object, or by top-level `let` bindings (which
are not on the global object, IIRC).

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

RE: Standard modules - concept or concrete?

Domenic Denicola-2
From: Sam Tobin-Hochstadt


> This is close, but not quite right.  The rule is that any unbound variables in modules are errors.  The variables may be bound by import declarations, or by lexical bindings such as `var` or `let`, or by bindings on the global object, or by top-level `let` bindings (which are not on the global object, IIRC).

Is this correct then?

```js
Date.now();
```

is checked at compile time and found to be OK, because it is referencing a binding that is a property of the global object that exists at the time of static-checking. But

```js
setTimeout(() =>
    asdf(); // (A)
}, 5000);

setTimeout(() =>
    window.asdf = () =>; // (B)
}, 1000);
```

is checked at compile time and found to *error*, because (A) is referencing a binding that is a not a property of the global object at the time of static checking? (Assuming an `asdf` binding is not introduced through any of the other mechanisms you mention.) And this is true even though (B) adds such a property to the global object before (A) ever runs?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Tue, Jun 18, 2013 at 11:29 PM, Domenic Denicola
<[hidden email]> wrote:
> From: Sam Tobin-Hochstadt
>
>
>> This is close, but not quite right.  The rule is that any unbound variables in modules are errors.  The variables may be bound by import declarations, or by lexical bindings such as `var` or `let`, or by bindings on the global object, or by top-level `let` bindings (which are not on the global object, IIRC).
>
> Is this correct then?

Yes, the below is all correct.

Sam

>
> ```js
> Date.now();
> ```
>
> is checked at compile time and found to be OK, because it is referencing a binding that is a property of the global object that exists at the time of static-checking. But
>
> ```js
> setTimeout(() =>
>     asdf(); // (A)
> }, 5000);
>
> setTimeout(() =>
>     window.asdf = () =>; // (B)
> }, 1000);
> ```
>
> is checked at compile time and found to *error*, because (A) is referencing a binding that is a not a property of the global object at the time of static checking? (Assuming an `asdf` binding is not introduced through any of the other mechanisms you mention.) And this is true even though (B) adds such a property to the global object before (A) ever runs?
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Kevin Smith
But a compile-time error as Domenic is wondering?  That doesn't seem quite right to me.  I would think that those would be runtime errors (as is the case in strict-mode).  Otherwise this is a big semantic change that I haven't previously considered.

{ Kevin }

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

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
First, I meant what I said in my previous email -- that program is a
compile time error inside a module.

Second, the meaning of that program doesn't change in strict mode.  If
the reference is evaluated before the assignment, it's a
ReferenceError even in non-strict mode.  If the assignment is
evaluated first, it will work even in strict mode.

Sam

On Wed, Jun 19, 2013 at 9:53 AM, Kevin Smith <[hidden email]> wrote:
> But a compile-time error as Domenic is wondering?  That doesn't seem quite
> right to me.  I would think that those would be runtime errors (as is the
> case in strict-mode).  Otherwise this is a big semantic change that I
> haven't previously considered.
>
> { Kevin }
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Standard modules - concept or concrete?

Kevin Smith
OK - I see it on the wiki here:

"Compilation resolves and validates all variable definitions and references"

It still seems odd to me that we're going to check a dynamic object (the global object) at link-time for references.  What if the global object is changed after the linking pass, but before the module executes?  Does the variable reference still point to the old thing?

    // Before linking, window.bar = "before"

    // foo.js
    bar = "after";

    // main.js
    import "foo";
    console.log(bar); // "before"?


Thanks,

{ Kevin }

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

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Wed, Jun 19, 2013 at 11:37 AM, Kevin Smith <[hidden email]> wrote:

> OK - I see it on the wiki here:
>
> "Compilation resolves and validates all variable definitions and references"
>
> It still seems odd to me that we're going to check a dynamic object (the
> global object) at link-time for references.  What if the global object is
> changed after the linking pass, but before the module executes?  Does the
> variable reference still point to the old thing?
>
>     // Before linking, window.bar = "before"
>
>     // foo.js
>     bar = "after";
>
>     // main.js
>     import "foo";
>     console.log(bar); // "before"?

This produces "after" -- mutable variables are still mutable.  Saving
an old version would be pretty strange.

Note that there are situations where you can still get a
ReferenceError inside a module, by deleting properties off of
`window`.   Ruling this out would require:

1. not giving modules access to the global scope, or
2. changing the global object when compiling modules

Neither of these seem like good ideas.

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

Re: Standard modules - concept or concrete?

Kevin Smith


Note that there are situations where you can still get a
ReferenceError inside a module, by deleting properties off of
`window`.   Ruling this out would require:

1. not giving modules access to the global scope, or
2. changing the global object when compiling modules

Neither of these seem like good ideas.


I agree.  I wonder, though, why my previous example should work, but this should fail:

    // Before linking, window.bar is not defined
    
    // foo.js
    window.bar = "bar";

    // main.js
    import "foo";
    console.log(bar); // Link time error

But if we ran "foo" in a previous linking/execution pass, then it would work.

Since this is a departure from the current non-module handling of global object variable references, what is the motivation?

{ Kevin }

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

Re: Standard modules - concept or concrete?

Kevin Smith
I would think the advantage of running compile-time checks against the global object is that it can catch errors that we currently use linters for:

    // OOPS - forgot this line!
    // import { x } from "foo";

    function someRareCase() {
        x(); // Reference error?
    }

That's useful, but it comes at the price of treating the global object as if it were a static thing, and not dynamic.  From my point of view, though, a dynamic global object is just how it goes with Javascript.  I think this kind of static checking should be left to linters, unless we are adopting a policy of actively discouraging dynamism for the global object.

{ Kevin }


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

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Thu, Jun 20, 2013 at 9:55 AM, Kevin Smith <[hidden email]> wrote:

> I would think the advantage of running compile-time checks against the
> global object is that it can catch errors that we currently use linters for:
>
>     // OOPS - forgot this line!
>     // import { x } from "foo";
>
>     function someRareCase() {
>         x(); // Reference error?
>     }
>
> That's useful, but it comes at the price of treating the global object as if
> it were a static thing, and not dynamic.  From my point of view, though, a
> dynamic global object is just how it goes with Javascript.  I think this
> kind of static checking should be left to linters, unless we are adopting a
> policy of actively discouraging dynamism for the global object.

We could:

1. Give up on static checking of unbound variables in modules.
2. Take the global object off the scope chain in modules.
3. Adopt a compromise.

We think static checking for unbound variables is valuable, and
letting people write `console.log` without having to import anything
is valuable. Thus, option 3.

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

Re: Standard modules - concept or concrete?

Andreas Rossberg-4
In reply to this post by Kevin Smith
On 20 June 2013 15:55, Kevin Smith <[hidden email]> wrote:

> I would think the advantage of running compile-time checks against the
> global object is that it can catch errors that we currently use linters for:
>
>     // OOPS - forgot this line!
>     // import { x } from "foo";
>
>     function someRareCase() {
>         x(); // Reference error?
>     }
>
> That's useful, but it comes at the price of treating the global object as if
> it were a static thing, and not dynamic.  From my point of view, though, a
> dynamic global object is just how it goes with Javascript.  I think this
> kind of static checking should be left to linters, unless we are adopting a
> policy of actively discouraging dynamism for the global object.

This actually is the sort of thing that can be difficult to check for
off-line linters, because the use of global variables may depend on
some staged dynamic configuration that a linter cannot easily see,
verify, or assume.

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

Re: Standard modules - concept or concrete?

Kevin Smith


This actually is the sort of thing that can be difficult to check for
off-line linters, because the use of global variables may depend on
some staged dynamic configuration that a linter cannot easily see,
verify, or assume.


That's pretty much true for everything about javascript : )

In my usage of linters for this task (using my own linters of course), I would have a predefined set of global variables that are "allowed" - essentially treating the global object as if it were static for the purposes of linting.

{ Kevin }


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

Re: Standard modules - concept or concrete?

Kevin Smith
In reply to this post by Sam Tobin-Hochstadt

We think static checking for unbound variables is valuable, and
letting people write `console.log` without having to import anything
is valuable. Thus, option 3.


I think that's fine, if we're willing to discourage dynamic usage of the global object for unbound variables.  Static checking of the global object might create some iffy edge cases for users who want to treat the global object as a more dynamic thing.

{ Kevin }


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

Re: Standard modules - concept or concrete?

Kevin Smith
I wonder, though, if this might create issues for polyfilling:

    // polyfillz.js
    if (this.Promise ===  void 0)
        this.Promise = function() { ... }

    // main.js
    import "polyfillz.js";
    new Promise();

This would refuse to compile, right?  We'd have to introduce all of our polyfills in a separate (previous) compilation/execution cycle.

{ Kevin }

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

Re: Standard modules - concept or concrete?

Sam Tobin-Hochstadt
On Thu, Jun 20, 2013 at 10:26 AM, Kevin Smith <[hidden email]> wrote:

> I wonder, though, if this might create issues for polyfilling:
>
>     // polyfillz.js
>     if (this.Promise ===  void 0)
>         this.Promise = function() { ... }
>
>     // main.js
>     import "polyfillz.js";
>     new Promise();
>
> This would refuse to compile, right?  We'd have to introduce all of our
> polyfills in a separate (previous) compilation/execution cycle.

Yes, like so:

    <script src="polyfillz.js"/>

Note that this is already the way people suggest using polyfills; see
[1] for an example.

Sam

[1] https://github.com/axemclion/IndexedDBShim
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12