ModuleImport

2014-06-19 Thread David Herman
Thanks to everyone for working through the issues around ModuleImport. I know 
it's been frustrating, but the discussions have really helped clarify the key 
constraints.

## Constraints

First, let me restate the most important arguments. In favor of removal:

* **The syntactic distinction between ModuleImport and default import is 
vague.**

We've consistently seen confusion between the semantics of ModuleImport and 
default export. While certainly some of the confusion might be chalked up to 
misinformation and lack of documentation, we've seen people be confused by this 
even when correctly explained the semantics. The problem with the syntax is 
that the only visual distinction is the initial keyword (`module` vs `import`), 
and it's not clear from that keyword which concept you're talking about. (Once 
you've internalized the structure of module instance objects, you get a hint 
from the `module` keyword, but that doesn't help people who are just learning 
the system, particularly if they're already familiar with other JS module 
systems.)

Against removal:

* **Without ModuleImport, authors of multi-export modules would be pressured to 
circumvent the named exports functionality.**

Without ModuleImport, clients of multi-export modules have two options. Either 
they use named import:
```js
import { readFile, writeFile } from fs;
```
or if they want to explicitly namespace those functions, they have to use the 
dynamic API:
```js
import fs; // state the dependency
var fs = this.get(fs);
```
That's inconvenient, confusing, and makes you feel like you're stepping outside 
the normal usage patterns intended for the system. Since this is a choice 
forced on the clients of a module, the module author will feel pressure to 
circumvent the named export feature altogether and instead export a default 
object with all the properties. This is bad -- it creates pressure for people 
to abandon part of the module system.

## Conclusion

Here's the conclusion I've come to based on all of the above.

* **We need a form like ModuleImport.**

As many have said, clients of named-export modules need the freedom to choose 
whether to explicitly namespace those imports, and they need a syntax that 
doesn't feel like they've stepped outside the normal system.

* **The current syntax of ModuleImport is wrong.**

The confusion reported in developer feedback is real, and it's important.

* **The syntax should still favor default import.**

ES6 favors the single/default export style, and gives the sweetest syntax to 
importing the default. Importing named exports can and even should be slightly 
less concise.

* **A better ModuleImport syntax is possible, and we should settle it soon.**

I'll propose a better ModuleImport syntax below. Syntax being syntax, everyone 
will of course unsheathe their bikeshed paintbrush. That's OK. The champions 
will keep it from going on unbounded and help settle the debate, and we'll make 
sure to capture the conclusion in the next TC39 meeting.

I do acknowledge the concerns about reopening topics for debate and delay. But 
given the usability feedback, I think this case is worth fixing. We should 
resolve it for ES6, perhaps in part because it's less editorial work to change 
the ModuleImport production than to defer it, but more because I don't want to 
delay the resolution so that implementations can ship the better syntax. But 
keep in mind it doesn't matter what spec it lands in as long as implementations 
are shipping it. We're still in the early days of transpiler implementations, 
and there are no native implementations of modules yet. So there's time, as 
long as we don't let the bikeshed go on forever. So let's get to it!

## Proposal

OK, so we're talking about a better syntax for importing a module and binding 
its named exports to a variable (as distinct from importing a module and 
binding its default export to a variable). Here's my proposal:
```js
import * as fs from fs; // importing the named exports as an object
import Dict from dict;  // importing a default export, same as ever
```

Why is this better? Because it dovetails with the named export syntax, **which 
makes it clear that it's binding `fs` to the named exports.** It saves the 
reader from having to know that the module instance object is not the same 
thing as the default export.

So there you have it... Feedback welcome, and as always we'll collect it all, 
weigh it, and try to shepherd consensus.

Oh, and just to put parameters on the discussion:

* **I'm not proposing additional new import forms.**

If this syntax is future-compatible with other possible syntactic forms, that's 
great, but that's not what we're discussing.

* **I'm not interested in discussing changes to the rest of the module syntax.**

This isn't the time or place to redesign the whole system.

* **The `this` binding in modules is a separate topic.**

The `this` binding in modules can be discussed independently of this topic.

tl;dr we're 

Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
That’s a good solution. Logically, `import { * } from fs` may make more 
sense, but I prefer the “unbraced” asterisk, because it results in less clutter.

Does the proposed syntax clash with `export * FromClause` (which, I’m assuming, 
re-exports everything, not just the named exports)?

I’d prefer it if named exports and a default export were mutually exclusive, 
but I understand that is off the table(?) Which is also fine with me…

Axel

On Jun 19, 2014, at 10:15 , David Herman dher...@mozilla.com wrote:

 ## Proposal
 
 OK, so we're talking about a better syntax for importing a module and binding 
 its named exports to a variable (as distinct from importing a module and 
 binding its default export to a variable). Here's my proposal:
 ```js
 import * as fs from fs; // importing the named exports as an object
 import Dict from dict;  // importing a default export, same as ever
 ```

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread David Herman
On Jun 19, 2014, at 2:03 AM, Axel Rauschmayer a...@rauschma.de wrote:

 Does the proposed syntax clash with `export * FromClause` (which, I’m 
 assuming, re-exports everything, not just the named exports)?

No inconsistency; it imports everything. Exactly the same semantics as always, 
just a change in surface syntax. Remember that the module instance object 
contains all named exports, but the default export is simply an export with the 
name `default`.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread Till Schneidereit
On Thu, Jun 19, 2014 at 1:39 AM, Allen Wirfs-Brock al...@wirfs-brock.com
wrote:


 On Jun 18, 2014, at 4:12 PM, Brendan Eich wrote:

  Allen Wirfs-Brock wrote:
  The spec. current says throw for this Symbol.prototype case.  The
 (reasonable) opposing view is that toString should never throw.  Other than
 the protoype-is-not-an-instance it all about unlikely edge cases where
 toString methods are applied to the wrong kind of object.
 
  js Object.create(null).toString()
  typein:1:0 TypeError: Object.create(...).toString is not a function
 
  It happens. Better to catch that error (Symbol.prototype flowing into an
 implicit conversion) early?

 which is pretty much the approach the ES6 spec. has taken WRT toString up
 to now. Tension between catching invalid iplicit toString conversions and
 reliable toString for debugging.


I'd posit that there are three different cases for toString:
1) (explictly or implicitly) calling foo.toString, where `foo` is any of
the objects that, by default, exist in a JS global without any user code
having run
2) (explicitly or implicitly) calling foo.toString, where `foo` is some
content script-generated object
3) explicitly calling bar.toString.call(foo), where `foo` and `bar` are
arbitrary objects

The current (ES5) state of things is that 1) can never throw, while both 2)
and 3) might. The current ES6 draft would move 1) over into the latter
camp. I think *that* is the crucial thing to prevent. It's just wrong for
the language to essentially say here's a bunch of objects. They have
methods. But don't call all of them. Finding out which ones aren't allowed
to be called is left as an excercise to the reader.

Theoretically, Scott's #d still hold the most appeal to me. However, I
don't think it works in a multi-Realm world, hence theoretically. Given
that, it's #b or #c, where, again, I don't much care which one it'll be.


 At any rate, run time tools can really depend upon toString working,  They
 probably should use something like:

 function reliableToString(obj) {
try {return obj.toString()} catch (e) {
try {return {}.toString.call(obj)} catch (f) {
  return [ object ???]}
 }
 }
 }


True. It's not clear to me that the web as a whole knows this, though, and
the current state of the spec might teach it the hard way.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Michał Gołębiowski
Thanks, Dave, for bringing that up, it shows you're open for feedback. That
said (bikeshed begins), what's wrong with:
```js
import fs as fs;
```
? I feel that a lot of effort went in ES6 into reducing boilerplate via
e.g. arrow functions, classes etc. but if you start with Node's require,
this adds clutter. Compare these 3 forms of importing all the module
lodash bindings to an object _:
```js
var _ = require(lodash); // Node
import * as _ from lodash; // Dave's syntax
import lodash as _;
```
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
This is a key sentence in David’s proposal: “ES6 favors the single/default 
export style, and gives the sweetest syntax to importing the default. Importing 
named exports can and even should be slightly less concise.”


On Jun 19, 2014, at 12:31 , Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback. That 
 said (bikeshed begins), what's wrong with:
 ```js
 import fs as fs;
 ```
 ? I feel that a lot of effort went in ES6 into reducing boilerplate via e.g. 
 arrow functions, classes etc. but if you start with Node's require, this adds 
 clutter. Compare these 3 forms of importing all the module lodash bindings 
 to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Calvin Metcalf
One other option could be for import name from 'path'  to resolve to the
module body there is no default export, thanks to the static analysis
you'll always know when default is present.

The import 'path'/this.get syntax is a lot less burdensome if it's only
required by edge cases like needing both default export and all the named
ones.
On Jun 19, 2014 6:32 AM, Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback.
 That said (bikeshed begins), what's wrong with:
 ```js
 import fs as fs;
 ```
 ? I feel that a lot of effort went in ES6 into reducing boilerplate via
 e.g. arrow functions, classes etc. but if you start with Node's require,
 this adds clutter. Compare these 3 forms of importing all the module
 lodash bindings to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Michał Gołębiowski
On Thu, Jun 19, 2014 at 12:40 PM, Axel Rauschmayer a...@rauschma.de wrote:

 This is a key sentence in David’s proposal: “ES6 favors the single/default
 export style, and gives the sweetest syntax to importing the default.
 Importing named exports can and even should be slightly less concise.”


There are a lot of large modules that will not disappear overnight. I
assume ES6's recommendation for such things (Node's fs module, Lo-Dash) is
to make those container objects default exports?

-- 
Michał Gołębiowski
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Mark Volkmann
What is the behavior if a module doesn't define a default export and the syntax 
for importing the default export is used?

What is the behavior if a module only defines a default export and the syntax 
for importing named imports is used?

---
R. Mark Volkmann
Object Computing, Inc.

 On Jun 19, 2014, at 3:15 AM, David Herman dher...@mozilla.com wrote:
 
 Thanks to everyone for working through the issues around ModuleImport. I know 
 it's been frustrating, but the discussions have really helped clarify the key 
 constraints.
 
 ## Constraints
 
 First, let me restate the most important arguments. In favor of removal:
 
 * **The syntactic distinction between ModuleImport and default import is 
 vague.**
 
 We've consistently seen confusion between the semantics of ModuleImport and 
 default export. While certainly some of the confusion might be chalked up to 
 misinformation and lack of documentation, we've seen people be confused by 
 this even when correctly explained the semantics. The problem with the syntax 
 is that the only visual distinction is the initial keyword (`module` vs 
 `import`), and it's not clear from that keyword which concept you're talking 
 about. (Once you've internalized the structure of module instance objects, 
 you get a hint from the `module` keyword, but that doesn't help people who 
 are just learning the system, particularly if they're already familiar with 
 other JS module systems.)
 
 Against removal:
 
 * **Without ModuleImport, authors of multi-export modules would be pressured 
 to circumvent the named exports functionality.**
 
 Without ModuleImport, clients of multi-export modules have two options. 
 Either they use named import:
 ```js
 import { readFile, writeFile } from fs;
 ```
 or if they want to explicitly namespace those functions, they have to use the 
 dynamic API:
 ```js
 import fs; // state the dependency
 var fs = this.get(fs);
 ```
 That's inconvenient, confusing, and makes you feel like you're stepping 
 outside the normal usage patterns intended for the system. Since this is a 
 choice forced on the clients of a module, the module author will feel 
 pressure to circumvent the named export feature altogether and instead export 
 a default object with all the properties. This is bad -- it creates pressure 
 for people to abandon part of the module system.
 
 ## Conclusion
 
 Here's the conclusion I've come to based on all of the above.
 
 * **We need a form like ModuleImport.**
 
 As many have said, clients of named-export modules need the freedom to choose 
 whether to explicitly namespace those imports, and they need a syntax that 
 doesn't feel like they've stepped outside the normal system.
 
 * **The current syntax of ModuleImport is wrong.**
 
 The confusion reported in developer feedback is real, and it's important.
 
 * **The syntax should still favor default import.**
 
 ES6 favors the single/default export style, and gives the sweetest syntax to 
 importing the default. Importing named exports can and even should be 
 slightly less concise.
 
 * **A better ModuleImport syntax is possible, and we should settle it soon.**
 
 I'll propose a better ModuleImport syntax below. Syntax being syntax, 
 everyone will of course unsheathe their bikeshed paintbrush. That's OK. The 
 champions will keep it from going on unbounded and help settle the debate, 
 and we'll make sure to capture the conclusion in the next TC39 meeting.
 
 I do acknowledge the concerns about reopening topics for debate and delay. 
 But given the usability feedback, I think this case is worth fixing. We 
 should resolve it for ES6, perhaps in part because it's less editorial work 
 to change the ModuleImport production than to defer it, but more because I 
 don't want to delay the resolution so that implementations can ship the 
 better syntax. But keep in mind it doesn't matter what spec it lands in as 
 long as implementations are shipping it. We're still in the early days of 
 transpiler implementations, and there are no native implementations of 
 modules yet. So there's time, as long as we don't let the bikeshed go on 
 forever. So let's get to it!
 
 ## Proposal
 
 OK, so we're talking about a better syntax for importing a module and binding 
 its named exports to a variable (as distinct from importing a module and 
 binding its default export to a variable). Here's my proposal:
 ```js
 import * as fs from fs; // importing the named exports as an object
 import Dict from dict;  // importing a default export, same as ever
 ```
 
 Why is this better? Because it dovetails with the named export syntax, 
 **which makes it clear that it's binding `fs` to the named exports.** It 
 saves the reader from having to know that the module instance object is not 
 the same thing as the default export.
 
 So there you have it... Feedback welcome, and as always we'll collect it all, 
 weigh it, and try to shepherd consensus.
 
 Oh, and just to put parameters on the discussion:
 
 * **I'm 

Re: @@new

2014-06-19 Thread Jason Orendorff
On Wed, Jun 18, 2014 at 5:29 PM, Kevin Smith zenpars...@gmail.com wrote:
 I think Allen's suggestion of providing constructor arguments to @@create
 is promising.  That would allow the implementation to allocate and
 initialize an object in one go, if desired.  That seems to embody the
 advantages of fusing initialization and allocation, without the headache for
 the user.

 Never mind,  that doesn't work. Sorry for the noise.

I'd like to understand. Why doesn't it work?

-j
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Kevin Smith


 I'd like to understand. Why doesn't it work?


Allen wondered the same, so I'll just paste my reply to him:

So I was a little embarrassed about not thinking it through, and wanted to
just void the comment.

But specifically, if the subclass wants to have a different set of
constructor arguments than its base class, then presumably the subclass
would have to override @@create with that signature.

class MyMap extends Map {
constructor(a, b, c) { super(); /* other initialization */ }
static [Symbol.create](a, b, c) { return super(); }
}

Is that right?

That seems like too much of a burden for the user.  And besides, it
pollutes the nice separation of responsibilities that we currently have.

The current design does posit uninitialized objects, which implementers are
obviously uncomfortable with.  Could it be that we just haven't yet
developed the implementation techniques for dealing with such uninitialized
objects? Or is there a real problem with being able to observe them?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Jason Orendorff
On Wed, Jun 18, 2014 at 4:09 PM, Allen Wirfs-Brock
al...@wirfs-brock.com wrote:
 Jason covered the combinations: his proposal supports class subclassing 
 function, etc. What concretely do you mean here, if not that? If you mean 
 refactoring from one to the other, what observably differs?

 My understanding of the proposal was that:

 class F  {constructor(x) {this.foo=x}};

 turns into the equivalent of:

 function F(x) { /* ??? the initial message really isn't explicit about what 
 does here */ };
 F[Symbol.new] = {[Symbol.new](x) {  //use an object literal to create a 
 method kind of function
 var obj = super();
 obj.foo = x
 }}[Symbol.new].toMethod(F);

 which is quite different from you get for:

  function F(x) {this.foo=x};

But again, what user-observable difference are you pointing to? `new
F(0)` in either case creates a new object inheriting from F.prototype,
sets that object's foo property to 0, and returns that object.
Subclassing either one is just `class G extends F {...}`.

As a side note, just because you can write something in a complicated
way doesn't necessarily mean it's complicated. I think having `F()`
and `new F()` do the same thing is simpler for users than having them
do different things. Having a single hook for object creation is
simpler than having two (like C++) or three (like Ruby and Smalltalk).

`function F(x) {this.foo=x}` is short, not simple.

-j
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Jason Orendorff
On Wed, Jun 18, 2014 at 4:09 PM, Allen Wirfs-Brock
al...@wirfs-brock.com wrote:
 function F(x) { /* ??? the initial message really isn't explicit about what 
 does here */ };

I think focusing on what was in the initial message vs. what was
explained later (or remains open for discussion) does us all a
disservice. No proposal springs fully formed from Zeus' head. It's a
process.

-j
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Kevin Smith


 ```js
 import * as fs from fs; // importing the named exports as an object
 import Dict from dict;  // importing a default export, same as ever
 ```


It's a little wordy, but it fulfills the goals and feels pleasant to write.
 +1 from me.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread André Bargull
 The most important thing here (I agree with Andreas R.) is -- if 
possible -- avoiding uninitialized object observability.


I agree that uninitialized observability is a pain and has been a 
on-going source
of reentrancy bugs in the the more complex built-in constructors. I 
want to
explore whether making the constructor arguments available to @@create 
provides

an alternative way to eliminate that issue.


That means depending on the class/built-in a subclass needs to override 
either the @@create method or the constructor function or both?


For example let's take the Map built-in. The @@create method will 
initialise [[MapData]] to an empty list early on, that way Map instances 
are never observed uninitialised. Processing the iterable argument to 
fill the Map may either occur in @@create or in the Map constructor 
function. Subclasses will need to consult the specification to find out 
which method needs to be overridden if the iterable argument needs to be 
preprocessed.


For other (more special) built-ins like String/Number/Function/..., 
@@create will need to perform the complete initialisation including 
processing the arguments. Otherwise uninitialised objects are still 
observable. As a result subclasses are required to override @@create and 
overriding the constructor is a no-op (w.r.t. arguments handling).

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Erik Arvidsson
On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf calvin.metc...@gmail.com
wrote:

 One other option could be for import name from 'path'  to resolve to the
 module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

That is a refactoring hazard. If the module changes to add/remove the
default export the import will still succeed but the value is either a
module instance object or anything:

// a.js
export default class C { ... }

// importer.js
import A from './a';
new A();

Now a.js changes.

// a.js V2
export class C { ... }

// importer.js
import A from './a';
new A();  // TypeError: A is not a function

With this idea you cannot look at the import statement to see if the
imported binding is a module instance object or not.



  The import 'path'/this.get syntax is a lot less burdensome if it's only
 required by edge cases like needing both default export and all the named
 ones.
 On Jun 19, 2014 6:32 AM, Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback.
 That said (bikeshed begins), what's wrong with:
 ```js
 import fs as fs;
 ```
 ? I feel that a lot of effort went in ES6 into reducing boilerplate via
 e.g. arrow functions, classes etc. but if you start with Node's require,
 this adds clutter. Compare these 3 forms of importing all the module
 lodash bindings to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




-- 
erik
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread David Herman
On Jun 19, 2014, at 3:31 AM, Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback. That 
 said (bikeshed begins),

lol :)

 what's wrong with:
 ```js
 import fs as fs;
 ```

Indeed we've talked about that one before. Some objected to the inconsistency 
of having the binding appear at the end and not having the module name at the 
end (all other import forms have the binding on the left and the module name at 
the end). But more importantly, this doesn't help with the problem of visually 
disambiguating from importing the default export. To put it another way, the 
`*` is critical in the `* as _` syntax, because it makes it explicit that we're 
talking about the named exports.

 ? I feel that a lot of effort went in ES6 into reducing boilerplate via e.g. 
 arrow functions, classes etc. but if you start with Node's require, this adds 
 clutter. Compare these 3 forms of importing all the module lodash bindings 
 to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

My feeling is that the clutter is small, and it's acceptable to have it be 
slightly less minimal than default export since that is the case we are 
favoring. This isn't so cluttered as to be downright *punishing* multi-export 
utility modules (it's literally only two characters longer than your Node code, 
albeit admittedly a little chattier), but it's good that default import is the 
winner.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Calvin Metcalf
 With this idea you cannot look at the import statement to see if the
imported binding is a module instance object or not.

the flip side of that is that you don't need to know whether something is a
default export or a named export to import it e.g.

```js
export let foo = function () {}
export let bar = function () {}
```

and

```js
class Baz {
foo(){}
bar(){}
}

let baz = new Baz();
export default baz;
```

could both be imported the same.

On Thu, Jun 19, 2014 at 9:57 AM, Erik Arvidsson erik.arvids...@gmail.com
wrote:


 On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf calvin.metc...@gmail.com
 wrote:

 One other option could be for import name from 'path'  to resolve to the
 module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

 That is a refactoring hazard. If the module changes to add/remove the
 default export the import will still succeed but the value is either a
 module instance object or anything:

 // a.js
 export default class C { ... }

 // importer.js
 import A from './a';
 new A();

 Now a.js changes.

 // a.js V2
 export class C { ... }

 // importer.js
 import A from './a';
 new A();  // TypeError: A is not a function

 With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.



  The import 'path'/this.get syntax is a lot less burdensome if it's only
 required by edge cases like needing both default export and all the named
 ones.
 On Jun 19, 2014 6:32 AM, Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback.
 That said (bikeshed begins), what's wrong with:
 ```js
 import fs as fs;
 ```
 ? I feel that a lot of effort went in ES6 into reducing boilerplate via
 e.g. arrow functions, classes etc. but if you start with Node's require,
 this adds clutter. Compare these 3 forms of importing all the module
 lodash bindings to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




 --
 erik




-- 
-Calvin W. Metcalf
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread John Barton
Sorry to be dense, but I would appreciate more elaboration of this sentence:


On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de wrote:

 This is a key sentence in David’s proposal: “ES6 favors the single/default
 export style,


What is the single/default export style?  If I understand this claim, it
says that a module will typically contain a single export statement, either
named 'default' or not. Is there any evidence to support this? Everything
I've seen contradicts this claim, assuming I understand it.


 and gives the sweetest syntax to importing the default. Importing named
 exports can and even should be slightly less concise.”


Could you please give an example? In my experience, export default is
rare or at least divisive since it seems stylistically incompatible with
named exports.




 On Jun 19, 2014, at 12:31 , Michał Gołębiowski m.go...@gmail.com wrote:

 Thanks, Dave, for bringing that up, it shows you're open for feedback.
 That said (bikeshed begins), what's wrong with:
 ```js
 import fs as fs;
 ```
 ? I feel that a lot of effort went in ES6 into reducing boilerplate via
 e.g. arrow functions, classes etc. but if you start with Node's require,
 this adds clutter. Compare these 3 forms of importing all the module
 lodash bindings to an object _:
 ```js
 var _ = require(lodash); // Node
 import * as _ from lodash; // Dave's syntax
 import lodash as _;
 ```


 --
 Dr. Axel Rauschmayer
 a...@rauschma.de
 rauschma.de




 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Juan Ignacio Dopazo


On Thursday, June 19, 2014 5:17 AM, David Herman dher...@mozilla.com wrote:

```js
import * as fs from fs; // importing the named exports as an object
import Dict from dict;  // importing a default export, same as ever
```


My first reaction is to think that a lot of developers will ask: why can't I do 
`import * from 'fs';`?

But it's easier to teach than the alternative. And I agree with the premises: 
ModuleImport should be there and it should be less convenient than using the 
default export.

Thanks David!

Juan
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Duplicate property names (was Re: @@new)

2014-06-19 Thread Erik Arvidsson
On Wed, Jun 18, 2014 at 12:07 AM, Brendan Eich bren...@mozilla.org wrote:

 Domenic Denicola wrote:

 Another way of guiding the decision: I don't quite recall where the spec
 landed `{ x: 1, [x]: 2 }`, but we should probably be consistent with that.


 *Mark Miller:* I am ok with removing the constraint that duplicate dynamic
 object properties throw (in strict mode) with the caveat that we also
 remove the same constraint for duplicate static properties.

 from http://esdiscuss.org/notes/2014-06-06#rest-properties-
 and-spread-properties-sebastian-markb-ge-.


https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-06/jun-6.md#conclusionresolution-3

- For both strict and sloppy object literals, both computed and static
properties no longer have any duplicate name checking.

I would like this the above to be clarified.

At the f2f we were talking about spread in object literals.

var a = {x: 1, y: 2};
var b = {x: 3, ...a};

However, reading the notes the context is lost and it seems like we are
suggestion removing the duplicate property check added in ES5 for strict
mode.

-- 
erik
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread James Burke
On Thu, Jun 19, 2014 at 1:15 AM, David Herman dher...@mozilla.com wrote:
 ## Proposal

 OK, so we're talking about a better syntax for importing a module and binding 
 its named exports to a variable (as distinct from importing a module and 
 binding its default export to a variable). Here's my proposal:
 ```js
 import * as fs from fs; // importing the named exports as an object
 import Dict from dict;  // importing a default export, same as ever
 ```

Two other possibilities:

1) Only allow export default or named exports, not both.

The reason default export is used in module systems today is because
there is just one thing that wants to be exported, and it does not
matter what its name is because it is indicated by the module ID.
Sometimes it is also easier to just use an object literal syntax for
the export than expanding that out into individual export statements.

Allowing both default and named exports from the same module is
providing this syntax/API extension. If there are ancillary
capabilities available, a submodule in a package is more likely the
way it will be used, accessed as a default export via a module ID like
‘mainModule/sub', instead of wanting to use a default and named export
from the same module.

It would look like this:

import fs from ‘fs’; // only has named exports, so get object holding
all the exports
import { readFile } from ‘fs’; // only the readFile export
import Dict from ‘dict’; // a default export

— or —

2) Only allow `export` of one thing from a module, and `import {}`
just means allowing getting the first property on that export. This
removes the named export checking, but that benefit was always a bit
weak, even weaker with the favoring of default export.

//d.js, module with a default export, note it does not need a name,
//`export` can only appear once in a file.
export function() {};

//fs.js, module with “multiple” us
export {
  readFile: function(){}
};

//main.js using ‘d’ and ‘fs'
import d from ‘d’;
import { readFile } from ‘fs’;

—

Both of those possibilities also fix the disjointed Sytem.import() use
with a default export. No need to know that a `.default` is needed to
get the usable part. It will match the `import Name from ‘id’` syntax
better.

James
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Jacob Gable


 On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf calvin.metc...@gmail.com
 wrote:

 One other option could be for import name from 'path'  to resolve to the
 module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

 That is a refactoring hazard. If the module changes to add/remove the
 default export the import will still succeed but the value is either a
 module instance object or anything:

 // a.js
 export default class C { ... }

 // importer.js
 import A from './a';
 new A();

 Now a.js changes.

 // a.js V2
 export class C { ... }

 // importer.js
 import A from './a';
 new A();  // TypeError: A is not a function

 With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.



For what it's worth, I have built a sort-of static analysis tool that would
give you visibility to these sort of refactoring changes.  We currently use
it on our code base of around 250 module files that are transpiled on
deployment.

- es6-import-validate, https://github.com/sproutsocial/es6-import-validate
- Also available as a grunt plugin,
https://github.com/sproutsocial/grunt-es6-import-validate

Jacob
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Duplicate property names (was Re: @@new)

2014-06-19 Thread Mark S. Miller
Yes. For both strict and sloppy, for both static/literal and
dynamic/computed, duplicate property names/symbols in object literals are
no longer an error. Instead, in left-to-right order, each cause the
equivalent of a [[DefineOwnProperty]] on the new object, so that rightward
definitions silently overwrite conflicting leftward definitions. This
should not result in any change to sloppy literals. It just makes strict
literals, regarding this issue alone, act like sloppy literals.  (Once we
have a way to express that a property is to be initialized to a
non-configurable state, we'll need to revisit this. But that's after ES6.)

Since the object is a new normal object, i.e., not exotic and especially
not a proxy, no one should ever be able to observe the object until its
initialization is complete.

If linters want to warn about statically determined duplicate properties,
that is of course their business, and is fine.



On Thu, Jun 19, 2014 at 7:47 AM, Erik Arvidsson erik.arvids...@gmail.com
wrote:

 On Wed, Jun 18, 2014 at 12:07 AM, Brendan Eich bren...@mozilla.org
 wrote:

 Domenic Denicola wrote:

 Another way of guiding the decision: I don't quite recall where the spec
 landed `{ x: 1, [x]: 2 }`, but we should probably be consistent with that.


 *Mark Miller:* I am ok with removing the constraint that duplicate
 dynamic object properties throw (in strict mode) with the caveat that we
 also remove the same constraint for duplicate static properties.

 from http://esdiscuss.org/notes/2014-06-06#rest-properties-
 and-spread-properties-sebastian-markb-ge-.



 https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-06/jun-6.md#conclusionresolution-3

 - For both strict and sloppy object literals, both computed and static
 properties no longer have any duplicate name checking.

 I would like this the above to be clarified.

 At the f2f we were talking about spread in object literals.

 var a = {x: 1, y: 2};
 var b = {x: 3, ...a};

 However, reading the notes the context is lost and it seems like we are
 suggestion removing the duplicate property check added in ES5 for strict
 mode.

 --
 erik

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss




-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Duplicate property names (was Re: @@new)

2014-06-19 Thread Mark Miller
Regarding Domenic's question:


Domenic Denicola wrote:

 Another way of guiding the decision: I don't quite recall where the
 spec landed `{ x: 1, [x]: 2 }`, but we should probably be consistent with
 that.



The initial value of the x property would be 2. It should not be observable
that it was 1 at an intermediate stage of the initialization.

-- 
  Cheers,
  --MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Standard builtins' prototypes and toString

2014-06-19 Thread Andrea Giammarchi
Can i bring back the good old JScript unknown? :P

Sent from my Windows Phone From: Brendan Eich
Sent: ‎6/‎18/‎2014 17:15
To: Allen Wirfs-Brock
Cc: Mark S. Miller; Mark Miller; Erik Arvidsson; Jason Orendorff;
es-discuss@mozilla.org list
Subject: Re: Standard builtins' prototypes and toString
Allen Wirfs-Brock wrote:
 [ object ???]

[object WTF]

:-P

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Chris Toshok
On Thu, Jun 19, 2014 at 7:13 AM, Calvin Metcalf calvin.metc...@gmail.com
wrote:

  With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.

 the flip side of that is that you don't need to know whether something is
 a default export or a named export to import it e.g.



and elsewhere James Burke wrote:



 1) Only allow export default or named exports, not both.


I wrote about both of these issues here the other day:


https://blog.toshokelectric.com/too-little-too-late-my-thoughts-on-es6-modules/

IMO you can't really implement Calvin's suggestion without making
default+named exports an early error, since you don't know where the
bindings should come from if a module contains both.

This would be great from the perspective of decoupling import/export
syntaxes.  But mutable bindings gum up the works, in that they provide
another avenue for anti-refactoring pressure to flow from module consumer
to module author, and the proposed syntax changes here (not by David) as
well as in my post would make their behavior even more of a hazard.  The
syntaxes need to remain coupled in some form because you really *do* want
to know if you're getting a mutable binding or not.

David's `import * as foo from 'foo'` proposal gets us close enough to the
ideal of what's possible now, that it's definitely a +1 here.

ES6 favors the single/default export style, and gives the sweetest syntax
 to importing the default


Coupling in action :/
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Chris Toshok
On Thu, Jun 19, 2014 at 6:57 AM, Erik Arvidsson erik.arvids...@gmail.com
wrote:


 On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf calvin.metc...@gmail.com
 wrote:

 One other option could be for import name from 'path'  to resolve to the
 module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

 That is a refactoring hazard. If the module changes to add/remove the
 default export the import will still succeed but the value is either a
 module instance object or anything:

 // a.js
 export default class C { ... }

 // importer.js
 import A from './a';
 new A();

 Now a.js changes.

 // a.js V2
 export class C { ... }

 // importer.js
 import A from './a';
 new A();  // TypeError: A is not a function

 With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.


I think you're example misses one point - The module author changed the
exported api, going from exporting a function named C to exporting an
object with a property named C.  Problems caused by this refactoring would
exist regardless of Calvin's suggestion.

Calvin's suggestion would allow the following refactoring to be done by the
module author without impacting his users, something not possible with
current ES6:

```js
// a.js V1
export default { C: class C { ... } }

// a.js V2
export class C { ... }
```

The refactoring hazard is real, but exists iff the module consumer uses
implicit exports (i.e. an Object.prototype method with the above default
export).  This is another reason why the named export form is better -
everything is explicit.  IMO the only good reason to use default export is
to export a single function.

-chris
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread Allen Wirfs-Brock

On Jun 19, 2014, at 3:18 AM, Till Schneidereit wrote:

 On Thu, Jun 19, 2014 at 1:39 AM, Allen Wirfs-Brock al...@wirfs-brock.com 
 wrote:
 
 On Jun 18, 2014, at 4:12 PM, Brendan Eich wrote:
 
  Allen Wirfs-Brock wrote:
  The spec. current says throw for this Symbol.prototype case.  The 
  (reasonable) opposing view is that toString should never throw.  Other 
  than the protoype-is-not-an-instance it all about unlikely edge cases 
  where toString methods are applied to the wrong kind of object.
 
  js Object.create(null).toString()
  typein:1:0 TypeError: Object.create(...).toString is not a function
 
  It happens. Better to catch that error (Symbol.prototype flowing into an 
  implicit conversion) early?
 
 which is pretty much the approach the ES6 spec. has taken WRT toString up to 
 now. Tension between catching invalid iplicit toString conversions and 
 reliable toString for debugging.
 
 I'd posit that there are three different cases for toString:
 1) (explictly or implicitly) calling foo.toString, where `foo` is any of the 
 objects that, by default, exist in a JS global without any user code having 
 run
 2) (explicitly or implicitly) calling foo.toString, where `foo` is some 
 content script-generated object
 3) explicitly calling bar.toString.call(foo), where `foo` and `bar` are 
 arbitrary objects
 
 The current (ES5) state of things is that 1) can never throw, while both 2) 
 and 3) might. The current ES6 draft would move 1) over into the latter camp. 
 I think *that* is the crucial thing to prevent. It's just wrong for the 
 language to essentially say here's a bunch of objects. They have methods. 
 But don't call all of them. Finding out which ones aren't allowed to be 
 called is left as an excercise to the reader.
 
 Theoretically, Scott's #d still hold the most appeal to me. However, I don't 
 think it works in a multi-Realm world, hence theoretically. Given that, 
 it's #b or #c, where, again, I don't much care which one it'll be.

Or even in a single Realm world, it isn't clear how:
   (class extends Date {}).prototype.toString()
would recognize that is is dealing with a prototype rather than a Date 
instance. 

I basically agree with you conclusion. An the conserve thing to do is to try to 
minimize legacy compat. To me, that says that for Date, Number, Boolean, 
String, RegExp we should do (c).  For new kinds of objects that don't exist in 
ES5 and which have internal state dependent toStrings we should do (b).  

I'll update the spec. accordingly.

Note that for the (c) cases this introduces a different breaking change: ES5 
specifies that String.prototype.toString.call({}) throws a TypeError but the 
(c) based change will return the empty string for that case. Hopefully, that is 
a change the web can live with.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread C. Scott Ananian
While we're on the topic, shall we discuss `valueOf()`?  Should it get the
same treatment?
  --scott
On Jun 19, 2014 1:28 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote:


 On Jun 19, 2014, at 3:18 AM, Till Schneidereit wrote:

 On Thu, Jun 19, 2014 at 1:39 AM, Allen Wirfs-Brock al...@wirfs-brock.com
 wrote:


 On Jun 18, 2014, at 4:12 PM, Brendan Eich wrote:

  Allen Wirfs-Brock wrote:
  The spec. current says throw for this Symbol.prototype case.  The
 (reasonable) opposing view is that toString should never throw.  Other than
 the protoype-is-not-an-instance it all about unlikely edge cases where
 toString methods are applied to the wrong kind of object.
 
  js Object.create(null).toString()
  typein:1:0 TypeError: Object.create(...).toString is not a function
 
  It happens. Better to catch that error (Symbol.prototype flowing into
 an implicit conversion) early?

 which is pretty much the approach the ES6 spec. has taken WRT toString up
 to now. Tension between catching invalid iplicit toString conversions and
 reliable toString for debugging.


 I'd posit that there are three different cases for toString:
 1) (explictly or implicitly) calling foo.toString, where `foo` is any of
 the objects that, by default, exist in a JS global without any user code
 having run
 2) (explicitly or implicitly) calling foo.toString, where `foo` is some
 content script-generated object
 3) explicitly calling bar.toString.call(foo), where `foo` and `bar` are
 arbitrary objects

 The current (ES5) state of things is that 1) can never throw, while both
 2) and 3) might. The current ES6 draft would move 1) over into the latter
 camp. I think *that* is the crucial thing to prevent. It's just wrong for
 the language to essentially say here's a bunch of objects. They have
 methods. But don't call all of them. Finding out which ones aren't allowed
 to be called is left as an excercise to the reader.

 Theoretically, Scott's #d still hold the most appeal to me. However, I
 don't think it works in a multi-Realm world, hence theoretically. Given
 that, it's #b or #c, where, again, I don't much care which one it'll be.


 Or even in a single Realm world, it isn't clear how:
(class extends Date {}).prototype.toString()
 would recognize that is is dealing with a prototype rather than a Date
 instance.

 I basically agree with you conclusion. An the conserve thing to do is to
 try to minimize legacy compat. To me, that says that for Date, Number,
 Boolean, String, RegExp we should do (c).  For new kinds of objects that
 don't exist in ES5 and which have internal state dependent toStrings we
 should do (b).

 I'll update the spec. accordingly.

 Note that for the (c) cases this introduces a different breaking change:
 ES5 specifies that String.prototype.toString.call({}) throws a TypeError
 but the (c) based change will return the empty string for that case.
 Hopefully, that is a change the web can live with.

 Allen



 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
On Jun 19, 2014, at 16:17 , John Barton johnjbar...@google.com wrote:

 Sorry to be dense, but I would appreciate more elaboration of this sentence:
 
 
 On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de wrote:
 This is a key sentence in David’s proposal: “ES6 favors the single/default 
 export style,
 
 What is the single/default export style?  If I understand this claim, it 
 says that a module will typically contain a single export statement, either 
 named 'default' or not. Is there any evidence to support this? Everything 
 I've seen contradicts this claim, assuming I understand it.

The syntax is ( 
https://people.mozilla.org/~jorendorff/es6-draft.html#sec-exports ):

export default AssignmentExpression

 and gives the sweetest syntax to importing the default. Importing named 
 exports can and even should be slightly less concise.”
 
 Could you please give an example? In my experience, export default is rare 
 or at least divisive since it seems stylistically incompatible with named 
 exports. 

I’m surprised, too. But that seems to be the feedback from people working with 
large module-based client-side projects and from the Node.js community: single 
exports are most common. I think in client-side projects, one class per module 
was reported as a frequent use case:

```js
// MyClass.js
export default class {
...
};

// main.js
import MyClass from MyClass;
```

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Matthew Robb
What if the `import module/id;` form was an expression that evaluated to
the module instance object.

This means everything stays as it is now except we remove the ModuleImport
form and if you want to use the module instance object you can do: `var foo
= import foo;`. You could also do `var { bar } = import foo;`


- Matthew Robb


On Thu, Jun 19, 2014 at 10:48 AM, Axel Rauschmayer a...@rauschma.de wrote:

 On Jun 19, 2014, at 16:17 , John Barton johnjbar...@google.com wrote:

 Sorry to be dense, but I would appreciate more elaboration of this
 sentence:


 On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de
 wrote:

 This is a key sentence in David’s proposal: “ES6 favors the
 single/default export style,


 What is the single/default export style?  If I understand this claim, it
 says that a module will typically contain a single export statement, either
 named 'default' or not. Is there any evidence to support this? Everything
 I've seen contradicts this claim, assuming I understand it.


 The syntax is (
 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-exports ):

 export default AssignmentExpression

 and gives the sweetest syntax to importing the default. Importing named
 exports can and even should be slightly less concise.”


 Could you please give an example? In my experience, export default is
 rare or at least divisive since it seems stylistically incompatible with
 named exports.


 I’m surprised, too. But that seems to be the feedback from people working
 with large module-based client-side projects and from the Node.js
 community: single exports are most common. I think in client-side projects,
 one class per module was reported as a frequent use case:

 ```js
 // MyClass.js
 export default class {
 ...
 };

 // main.js
 import MyClass from MyClass;
 ```

  --
 Dr. Axel Rauschmayer
 a...@rauschma.de
 rauschma.de




 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread Till Schneidereit
On Thu, Jun 19, 2014 at 7:46 PM, C. Scott Ananian ecmascr...@cscott.net
wrote:

 While we're on the topic, shall we discuss `valueOf()`?  Should it get the
 same treatment?
   --scott

Oh, yes: I always considered the `toString` discussion to really be about
`valueOf`, too.



 On Jun 19, 2014 1:28 PM, Allen Wirfs-Brock al...@wirfs-brock.com
 wrote:


 On Jun 19, 2014, at 3:18 AM, Till Schneidereit wrote:

 On Thu, Jun 19, 2014 at 1:39 AM, Allen Wirfs-Brock al...@wirfs-brock.com
  wrote:


 On Jun 18, 2014, at 4:12 PM, Brendan Eich wrote:

  Allen Wirfs-Brock wrote:
  The spec. current says throw for this Symbol.prototype case.  The
 (reasonable) opposing view is that toString should never throw.  Other than
 the protoype-is-not-an-instance it all about unlikely edge cases where
 toString methods are applied to the wrong kind of object.
 
  js Object.create(null).toString()
  typein:1:0 TypeError: Object.create(...).toString is not a function
 
  It happens. Better to catch that error (Symbol.prototype flowing into
 an implicit conversion) early?

 which is pretty much the approach the ES6 spec. has taken WRT toString
 up to now. Tension between catching invalid iplicit toString conversions
 and reliable toString for debugging.


 I'd posit that there are three different cases for toString:
 1) (explictly or implicitly) calling foo.toString, where `foo` is any of
 the objects that, by default, exist in a JS global without any user code
 having run
 2) (explicitly or implicitly) calling foo.toString, where `foo` is some
 content script-generated object
 3) explicitly calling bar.toString.call(foo), where `foo` and `bar` are
 arbitrary objects

 The current (ES5) state of things is that 1) can never throw, while both
 2) and 3) might. The current ES6 draft would move 1) over into the latter
 camp. I think *that* is the crucial thing to prevent. It's just wrong for
 the language to essentially say here's a bunch of objects. They have
 methods. But don't call all of them. Finding out which ones aren't allowed
 to be called is left as an excercise to the reader.

 Theoretically, Scott's #d still hold the most appeal to me. However, I
 don't think it works in a multi-Realm world, hence theoretically. Given
 that, it's #b or #c, where, again, I don't much care which one it'll be.


 Or even in a single Realm world, it isn't clear how:
(class extends Date {}).prototype.toString()
 would recognize that is is dealing with a prototype rather than a Date
 instance.

 I basically agree with you conclusion. An the conserve thing to do is to
 try to minimize legacy compat. To me, that says that for Date, Number,
 Boolean, String, RegExp we should do (c).  For new kinds of objects that
 don't exist in ES5 and which have internal state dependent toStrings we
 should do (b).

 I'll update the spec. accordingly.

 Note that for the (c) cases this introduces a different breaking change:
 ES5 specifies that String.prototype.toString.call({}) throws a TypeError
 but the (c) based change will return the empty string for that case.
 Hopefully, that is a change the web can live with.


Same for Date.prototype.toString({}) as mentioned above, yes. I'm
cautiously optimistic about these changes.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Erik Arvidsson
On Thu, Jun 19, 2014 at 1:23 PM, Chris Toshok tos...@gmail.com wrote:

 On Thu, Jun 19, 2014 at 6:57 AM, Erik Arvidsson erik.arvids...@gmail.com
 wrote:


 On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf calvin.metc...@gmail.com
  wrote:

 One other option could be for import name from 'path'  to resolve to the
 module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

 That is a refactoring hazard. If the module changes to add/remove the
 default export the import will still succeed but the value is either a
 module instance object or anything:

  // a.js
 export default class C { ... }

 // importer.js
 import A from './a';
 new A();

 Now a.js changes.

 // a.js V2
 export class C { ... }

 // importer.js
 import A from './a';
 new A();  // TypeError: A is not a function

 With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.


 I think you're example misses one point - The module author changed the
 exported api, going from exporting a function named C to exporting an
 object with a property named C.  Problems caused by this refactoring would
 exist regardless of Calvin's suggestion.


With the current spec this is a compile time error since a.js (V2) does not
export default.



 Calvin's suggestion would allow the following refactoring to be done by
 the module author without impacting his users, something not possible with
 current ES6:

 ```js
  // a.js V1
 export default { C: class C { ... } }


But this is the thing we are trying hard to have people never do.



 // a.js V2
 export class C { ... }
 ```

 The refactoring hazard is real, but exists iff the module consumer uses
 implicit exports (i.e. an Object.prototype method with the above default
 export).  This is another reason why the named export form is better -
 everything is explicit.  IMO the only good reason to use default export is
 to export a single function.

 -chris




-- 
erik
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Chris Toshok
On Thu, Jun 19, 2014 at 10:53 AM, Matthew Robb matthewwr...@gmail.com
wrote:

 What if the `import module/id;` form was an expression that evaluated to
 the module instance object.

 This means everything stays as it is now except we remove the ModuleImport
 form and if you want to use the module instance object you can do: `var foo
 = import foo;`. You could also do `var { bar } = import foo;`


This is essentially identical to System.get(foo), other than the
restriction on the argument being a string.  It lends itself to imperative
code when what you're after is a declarative syntax.

Making it an expression also means it's not a toplevel form in the grammar,
and so you could do things like this:

function foo() {
  if (someCondition)
return import module1;
  else
return import module2;
}

or even similar to your examples:

var { bar } = someCondition ? import foo : import bar;

which would make precise and static computation of the set of imports
impossible, and likely complicate module resolution as well.

-c
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Brendan Eich

Kevin Smith wrote:
The current design does posit uninitialized objects, which 
implementers are obviously uncomfortable with.  Could it be that we 
just haven't yet developed the implementation techniques for dealing 
with such uninitialized objects? Or is there a real problem with being 
able to observe them?


André replied well, but I just wanted to confirm: this is not some 
shallow whiny-implementor-knee-jerk-reaction problem. It's a real 
problem, for JS programmers as well as implementors.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread Allen Wirfs-Brock

On Jun 19, 2014, at 10:46 AM, C. Scott Ananian wrote:

 While we're on the topic, shall we discuss `valueOf()`?  Should it get the 
 same treatment?
   --scott
 

I don't think so. To me, toString is a special case because it is explicitly 
applied so often, particularly for debugging purposes. 

But valueOf is primarily invoked for implicit conversions in expressions.

Like I described earlier in this thread, TC39's assumption when it agreed to 
this ES design change was that the web did not generally depend upon using 
these existing ES3 generation  (or earlier) prototypes as instance objects.  In 
the case where we know that wasn't true (Function.prototype) we intentionally 
did not change the prototype to being a non-instance object.  We also agreed if 
we discovered other such dependencies we would change those prototypes back to 
being instance objects.

Discovering that one of these prototypes objects were being routinely used in 
expression contexts where valueOf was being implicitly applied would be 
evidence that that prototype needed to be handled in the legacy manner. But, we 
don't have any new evidence of that being the case.  Until there is some 
evidence, there isn't any reason to second guess the original analysis and 
TC39's decision.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Chris Toshok
On Thu, Jun 19, 2014 at 11:06 AM, Erik Arvidsson erik.arvids...@gmail.com
wrote:

 On Thu, Jun 19, 2014 at 1:23 PM, Chris Toshok tos...@gmail.com wrote:

 On Thu, Jun 19, 2014 at 6:57 AM, Erik Arvidsson erik.arvids...@gmail.com
  wrote:


 On Thu, Jun 19, 2014 at 6:41 AM, Calvin Metcalf 
 calvin.metc...@gmail.com wrote:

 One other option could be for import name from 'path'  to resolve to
 the module body there is no default export, thanks to the static analysis
 you'll always know when default is present.

 That is a refactoring hazard. If the module changes to add/remove the
 default export the import will still succeed but the value is either a
 module instance object or anything:

  // a.js
 export default class C { ... }

 // importer.js
 import A from './a';
 new A();

 Now a.js changes.

 // a.js V2
 export class C { ... }

 // importer.js
 import A from './a';
 new A();  // TypeError: A is not a function

 With this idea you cannot look at the import statement to see if the
 imported binding is a module instance object or not.


 I think you're example misses one point - The module author changed the
 exported api, going from exporting a function named C to exporting an
 object with a property named C.  Problems caused by this refactoring would
 exist regardless of Calvin's suggestion.


 With the current spec this is a compile time error since a.js (V2) does
 not export default.


Correct, but:

```js
// a.js
export default class C { ... }

// a.js V2
export default { C: class C { ... } }
```

The author changed the shape of the api here as well, preserving default
export.  Hazards abound once you have an importer.  That's what I meant by
problems caused by that sort of refactoring existing regardless of Calvin's
suggestion - if the shape changes there's nothing you can do in the general
case.

By adopting something like Calvin's suggestion we can remove a possible
module-side hazard, caused by the fact that the shape of an api
artificially differs between default export and named exports.




 Calvin's suggestion would allow the following refactoring to be done by
 the module author without impacting his users, something not possible with
 current ES6:

 ```js
  // a.js V1
 export default { C: class C { ... } }


 But this is the thing we are trying hard to have people never do.


What exactly is it we're trying to have people do?  never export more than
1 thing?  or never export an object literal, instead favoring
Object.create(null, { })?

-chris




 // a.js V2
 export class C { ... }
 ```

 The refactoring hazard is real, but exists iff the module consumer uses
 implicit exports (i.e. an Object.prototype method with the above default
 export).  This is another reason why the named export form is better -
 everything is explicit.  IMO the only good reason to use default export is
 to export a single function.

 -chris




 --
 erik

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Sam Tobin-Hochstadt
On Thu, Jun 19, 2014 at 2:29 PM, Chris Toshok tos...@gmail.com wrote:

 Calvin's suggestion would allow the following refactoring to be done by
 the module author without impacting his users, something not possible with
 current ES6:

 ```js
 // a.js V1
 export default { C: class C { ... } }


 But this is the thing we are trying hard to have people never do.


 What exactly is it we're trying to have people do?  never export more than 1
 thing?  or never export an object literal, instead favoring
 Object.create(null, { })?

If people want to export a bunch of distinct things, each of which
should be addressed under a separate name, they should use named
exports. If they want to export a single abstraction, then they should
use default export. If they want to use both, then they should do
both. But if they want to export a bunch of named things, they don't
need to use default export for that.

Sam
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Mark S. Miller
From a security perspective as well, I have always been uncomfortable with
observable uninitialized objects, though I have been too lazy to try
demonstrating a concrete attack.
 On Jun 19, 2014 11:12 AM, Brendan Eich bren...@mozilla.org wrote:

 Kevin Smith wrote:

 The current design does posit uninitialized objects, which implementers
 are obviously uncomfortable with.  Could it be that we just haven't yet
 developed the implementation techniques for dealing with such uninitialized
 objects? Or is there a real problem with being able to observe them?


 André replied well, but I just wanted to confirm: this is not some shallow
 whiny-implementor-knee-jerk-reaction problem. It's a real problem, for JS
 programmers as well as implementors.

 /be
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
On Jun 19, 2014, at 13:36 , Michał Gołębiowski m.go...@gmail.com wrote:

 On Thu, Jun 19, 2014 at 12:40 PM, Axel Rauschmayer a...@rauschma.de wrote:
 This is a key sentence in David’s proposal: “ES6 favors the single/default 
 export style, and gives the sweetest syntax to importing the default. 
 Importing named exports can and even should be slightly less concise.”
 
 There are a lot of large modules that will not disappear overnight. I assume 
 ES6's recommendation for such things (Node's fs module, Lo-Dash) is to make 
 those container objects default exports?

What are you saying? That you find this syntax too verbose?

```js
import * as fs from fs;
```

There is a little more clutter, but it’s only 2 characters longer than:

```js
var fs = require('fs');
```

This design decision does make sense if single-export modules are indeed much 
more common. It’s not what I expected, but it does seem to be the case.

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread John Barton
On Thu, Jun 19, 2014 at 10:48 AM, Axel Rauschmayer a...@rauschma.de wrote:

 On Jun 19, 2014, at 16:17 , John Barton johnjbar...@google.com wrote:

 Sorry to be dense, but I would appreciate more elaboration of this
 sentence:


 On Thu, Jun 19, 2014 at 3:40 AM, Axel Rauschmayer a...@rauschma.de
 wrote:

 This is a key sentence in David’s proposal: “ES6 favors the
 single/default export style,


 What is the single/default export style?  If I understand this claim, it
 says that a module will typically contain a single export statement, either
 named 'default' or not. Is there any evidence to support this? Everything
 I've seen contradicts this claim, assuming I understand it.


 The syntax is (
 https://people.mozilla.org/~jorendorff/es6-draft.html#sec-exports ):

 export default AssignmentExpression


Yes, but I was not clear: where is the evidence that ES6 favors this form
or single named export. My experience is opposite: the simple thing in ES6
is to export those things you want exported. If it's one thing, then one;
if it's 6 things then 6. One is not favored.



 and gives the sweetest syntax to importing the default. Importing named
 exports can and even should be slightly less concise.”


 Could you please give an example? In my experience, export default is
 rare or at least divisive since it seems stylistically incompatible with
 named exports.


 I’m surprised, too. But that seems to be the feedback from people working
 with large module-based client-side projects and from the Node.js
 community: single exports are most common.


I still don't get it. If you want one export, just export one thing. If you
want one big export object called _, then
  export var _ = {tons of stuffs}

One of the best references for devs to understand modules:
http://www.2ality.com/2013/07/es6-modules.html
says:
   The syntax for importing a default export is similar to normal
importing, but there are no braces

To me this is a bug not a feature; we should keep it simple and just have
one way to get one import from one export.

Just to make a connection to the topic, Dave's intro says:
   We've consistently seen confusion between the semantics of ModuleImport
and default export.

For me this confusion lands on default export equally as 'module` import.


I think in client-side projects, one class per module was reported as a
 frequent use case:

 ```js
 // MyClass.js
 export default class {
 ...
 };

 // main.js
 import MyClass from MyClass;
 ```

 --
 Dr. Axel Rauschmayer
 a...@rauschma.de
 rauschma.de




___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: ModuleImport

2014-06-19 Thread Domenic Denicola
From: es-discuss es-discuss-boun...@mozilla.org on behalf of David Herman 
dher...@mozilla.com

 * **Without ModuleImport, authors of multi-export modules would be pressured 
 to circumvent the named exports functionality.**

I am glad this point was recognized and acted upon. I feel listened-to :)

 * **The syntax should still favor default import.**

Glad that this piece of (strong, pervasive) community feedback is still being 
kept at the forefront, despite continual naysaying and disbelief from various 
quarters.

 I do acknowledge the concerns about reopening topics for debate and delay. 
 [...] But keep in mind it doesn't matter what spec it lands in as long as 
 implementations are shipping it.

This is part of a larger issue regarding the messaging of TC39 and versioned 
ECMAScript, which is somewhat out of touch with 
[reality](https://twitter.com/annevk/status/479334108150374401). I hope we can 
discuss this at the next TC39 meeting. But I don't mean to derail the thread.

 ```js
 import * as fs from fs; // importing the named exports as an object
 ```

This looks great. Other alternatives I thought about in response included 
`import { * } as fs from fs` and `import module fs from fs`, but upon 
consideration the brevity of yours wins.

I just hope we can do better documenting it, this time around, and fixing the 
many transpilers with their confusing semantics.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
 To me this is a bug not a feature; we should keep it simple and just have one 
 way to get one import from one export.
 
 Just to make a connection to the topic, Dave's intro says:
We've consistently seen confusion between the semantics of ModuleImport 
 and default export.
 
 For me this confusion lands on default export equally as 'module` import.

Personally, I agree, but many people feel strongly about the single-export use 
case. If default exports help with getting ES6 modules adopted more broadly 
then the slight increase in complexity is worth it.

Let’s compare. Your approach – slightly more redundant:

```js
// MyClass.js
export class MyClass { ... }
// main1.js
import { MyClass } from MyClass;

// myFunc.js
export function myFunc(...) { ... }
// main2.js
import { myFunc } from myFunc;
```

Default exports:

```js
// MyClass.js
export default class { ... };
// main1.js
import MyClass from MyClass;

// myFunc.js
export default function (...) { ... };
// main2.js
import myFunc from myFunc;
```

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Standard builtins' prototypes and toString

2014-06-19 Thread Till Schneidereit
On Thu, Jun 19, 2014 at 8:16 PM, Allen Wirfs-Brock al...@wirfs-brock.com
wrote:


 On Jun 19, 2014, at 10:46 AM, C. Scott Ananian wrote:

 While we're on the topic, shall we discuss `valueOf()`?  Should it get the
 same treatment?
   --scott


 I don't think so. To me, toString is a special case because it is
 explicitly applied so often, particularly for debugging purposes.

 But valueOf is primarily invoked for implicit conversions in expressions.

 Like I described earlier in this thread, TC39's assumption when it agreed
 to this ES design change was that the web did not generally depend upon
 using these existing ES3 generation  (or earlier) prototypes as instance
 objects.  In the case where we know that wasn't true (Function.prototype)
 we intentionally did not change the prototype to being a non-instance
 object.  We also agreed if we discovered other such dependencies we would
 change those prototypes back to being instance objects.

 Discovering that one of these prototypes objects were being routinely used
 in expression contexts where valueOf was being implicitly applied would be
 evidence that that prototype needed to be handled in the legacy manner.
 But, we don't have any new evidence of that being the case.  Until there is
 some evidence, there isn't any reason to second guess the original analysis
 and TC39's decision.


Ok, we'll try this in Nightly for Date.prototype and see if the assumption
holds. If it does, we'll continue with the rest.

I don't really know if Date.prototype is a good canary, but it's what I
have a mostly-finished patch for, and it doesn't seem to make too much of a
difference.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: ModuleImport

2014-06-19 Thread Domenic Denicola
From: es-discuss es-discuss-boun...@mozilla.org on behalf of James Burke 
jrbu...@gmail.com

 1) Only allow export default or named exports, not both.

As a modification of the current design, this hurts use cases like

```js
import glob, { sync as syncGlob } from glob;
import _, { zip } from underscore;
```

 2) Only allow `export` of one thing from a module, and `import {}` just means 
 allowing getting the first property on that export. This removes the named 
 export checking, but that benefit was always a bit weak, even weaker with the 
 favoring of default export.

I definitely believe that if the community were designing a syntax-based module 
format, incorporating the lessons learned so far, it would end up being along 
these lines. We've learned enough from browserify and RequireJS's 
CommonJS-wrapping to know that a top-level static import form has serious 
benefits, but we've also learned that `module.exports =` or `return` are the 
recommended and primary pattern, and you can always attach things to that 
default export as properties if necessary. (In CommonJS terms, we've learned 
that the benefits of typing `exports.x = y` instead of `module.exports.x = y` 
are not great enough to outweigh the minor confusion of having two export 
forms.)

Unfortunately, that's not the world we live in, and instead TC39 is designing a 
module system based on their own priorities. (Static checking of multi-export 
names, mutable bindings, etc.)

They've (wisely) decided to add affordances for the community's use cases, such 
as layering default exports on top of the multi-export model. As well as Dave's 
proposal in this thread to de-grossify usage of modules like fs. By doing so, 
they increase their chances of the module system being good enough for the 
community, so that the path of least resistance will be to adopt it, despite it 
not being designed for them primarily. It's still an open question whether this 
will be enough to win over the community from their existing tools, but with 
Dave's suggestion I think it has a better-than-even chance.

The transitional era will be a particularly vulnerable time for TC39's module 
design, however: as long as people are using transpilers, there's an 
opportunity for a particularly well-crafted, documented, and supported 
transpiler to give alternate semantics grounded in the community's preferred 
model, and win over enough of an audience to bleed the life out of TC39's 
modules. We already see signs of community interest in such ES6+ transpilers, 
as Angular illustrates. Even a transpiler that maintains a subset of ES6 syntax 
would work: if it supported only `export default x`, and then gave `import { x 
} from y` destructuring semantics instead of named-binding-import semantics, 
that would do the trick. Interesting times.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: @@new

2014-06-19 Thread Jason Orendorff
On Thu, Jun 19, 2014 at 8:39 AM, André Bargull andre.barg...@udo.edu wrote:
 That means depending on the class/built-in a subclass needs to override
 either the @@create method or the constructor function or both?

 For example let's take the Map built-in. The @@create method will initialise
 [[MapData]] to an empty list early on, that way Map instances are never
 observed uninitialised. Processing the iterable argument to fill the Map may
 either occur in @@create or in the Map constructor function.

Right. It should happen in the constructor. Map[@@create] can ignore
its arguments and return an empty Map. Subclasses will not need to
override @@create.

 Subclasses will need to consult the specification to find out which method
 needs to be overridden if the iterable argument needs to be preprocessed.

Or just try it and see what happens, which is what people seem to do
in practice. For Map, everything would just work.

However, TC39 could not then evolve Map[@@create] to take arguments in
a later edition. Existing subclasses would rely on Map[@@create]
ignoring its arguments.

 For other (more special) built-ins like String/Number/Function/..., @@create
 will need to perform the complete initialisation including processing the
 arguments. Otherwise uninitialised objects are still observable. As a result
 subclasses are required to override @@create and overriding the constructor
 is a no-op (w.r.t. arguments handling).

All correct.  :-|

For a time yesterday, I hoped that @@create + constructor would solve
everything. Classes that need to fully initialize would use @@create;
all other code would use constructor; nobody would have to care which.
But Kevin's right: subclasses would need to care, and it's a burden.

-j
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Axel Rauschmayer
All good points. I don’t see “TC39 versus the community”, though, I’m seeing 
many factions with different opinions.


On Jun 19, 2014, at 21:13 , Domenic Denicola dome...@domenicdenicola.com 
wrote:

 From: es-discuss es-discuss-boun...@mozilla.org on behalf of James Burke 
 jrbu...@gmail.com
 
 1) Only allow export default or named exports, not both.
 
 As a modification of the current design, this hurts use cases like
 
 ```js
 import glob, { sync as syncGlob } from glob;
 import _, { zip } from underscore;
 ```
 
 2) Only allow `export` of one thing from a module, and `import {}` just 
 means allowing getting the first property on that export. This removes the 
 named export checking, but that benefit was always a bit weak, even weaker 
 with the favoring of default export.
 
 I definitely believe that if the community were designing a syntax-based 
 module format, incorporating the lessons learned so far, it would end up 
 being along these lines. We've learned enough from browserify and RequireJS's 
 CommonJS-wrapping to know that a top-level static import form has serious 
 benefits, but we've also learned that `module.exports =` or `return` are the 
 recommended and primary pattern, and you can always attach things to that 
 default export as properties if necessary. (In CommonJS terms, we've 
 learned that the benefits of typing `exports.x = y` instead of 
 `module.exports.x = y` are not great enough to outweigh the minor confusion 
 of having two export forms.)
 
 Unfortunately, that's not the world we live in, and instead TC39 is designing 
 a module system based on their own priorities. (Static checking of 
 multi-export names, mutable bindings, etc.)
 
 They've (wisely) decided to add affordances for the community's use cases, 
 such as layering default exports on top of the multi-export model. As well as 
 Dave's proposal in this thread to de-grossify usage of modules like fs. By 
 doing so, they increase their chances of the module system being good 
 enough for the community, so that the path of least resistance will be to 
 adopt it, despite it not being designed for them primarily. It's still an 
 open question whether this will be enough to win over the community from 
 their existing tools, but with Dave's suggestion I think it has a 
 better-than-even chance.
 
 The transitional era will be a particularly vulnerable time for TC39's module 
 design, however: as long as people are using transpilers, there's an 
 opportunity for a particularly well-crafted, documented, and supported 
 transpiler to give alternate semantics grounded in the community's preferred 
 model, and win over enough of an audience to bleed the life out of TC39's 
 modules. We already see signs of community interest in such ES6+ 
 transpilers, as Angular illustrates. Even a transpiler that maintains a 
 subset of ES6 syntax would work: if it supported only `export default x`, and 
 then gave `import { x } from y` destructuring semantics instead of 
 named-binding-import semantics, that would do the trick. Interesting times.
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
 

-- 
Dr. Axel Rauschmayer
a...@rauschma.de
rauschma.de



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Kevin Smith


 Yes, but I was not clear: where is the evidence that ES6 favors this form
 or single named export. My experience is opposite: the simple thing in ES6
 is to export those things you want exported. If it's one thing, then one;
 if it's 6 things then 6. One is not favored.


FWIW, my experience (again) agrees with yours.  In all the ES6 modular code
I've written over the past couple of years, I've never felt a need or a
desire to use the default feature.  For me, personally, it's a
distraction.

However, we are where we are, and we need to make progress.  I think the
current design is something that we can all move forward with, even if we
don't agree with every design decision.  Put another way, you and I can
happily ignore the default feature, and have a bit of a laugh when we see
it resulting in confusion ; )

Kevin
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread James Burke
On Thu, Jun 19, 2014 at 12:13 PM, Domenic Denicola
dome...@domenicdenicola.com wrote:
 From: es-discuss es-discuss-boun...@mozilla.org on behalf of James Burke 
 jrbu...@gmail.com

 1) Only allow export default or named exports, not both.

 As a modification of the current design, this hurts use cases like

 ```js
 import glob, { sync as syncGlob } from glob;
 import _, { zip } from underscore;
 ```

It is just as likely the module author will specify sync and zip as
properties of their respective default export. Particularly since
those are coming from JS modules that come from existing module
systems.

So a destructuring assignment would be needed, following the default
import. It works out though, and is not that much more typing. That,
or those pieces would be available as ‘underscore/zip’ or ‘glob/sync'
imports.

The argument for allowing both a default and named exports seems
ill-defined based on data points known so far, and by avoiding it, it
reduces the number of import forms and aligns better with
System.import use.

James
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: ModuleImport

2014-06-19 Thread Domenic Denicola
From: James Burke [mailto:jrbu...@gmail.com] 

 The argument for allowing both a default and named exports seems ill-defined 
 based on data points known so far

I mean, it seems based on the idea that named exports are super-important, and 
that packages like glob and underscore should use them. I agree that it's 
unclear whether this will occur, but that seems to be the reasoning.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: ModuleImport

2014-06-19 Thread C. Scott Ananian
But why? The benefit of named exports in general is that you get the magic
mutable bindings -- but underscore and glob are mature libraries without
circular dependencies on other code.  They would gain exactly nothing from
switching to named exports.
  --scott
On Jun 19, 2014 4:16 PM, Domenic Denicola dome...@domenicdenicola.com
wrote:

 From: James Burke [mailto:jrbu...@gmail.com]

  The argument for allowing both a default and named exports seems
 ill-defined based on data points known so far

 I mean, it seems based on the idea that named exports are super-important,
 and that packages like glob and underscore should use them. I agree that
 it's unclear whether this will occur, but that seems to be the reasoning.
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Brendan Eich

Domenic Denicola wrote:


This is part of a larger issue regarding the messaging of TC39 and versioned 
ECMAScript, which is somewhat out of touch with 
[reality](https://twitter.com/annevk/status/479334108150374401).


(Spinach.)


  I hope we can discuss this at the next TC39 meeting. But I don't mean to 
derail the thread.


Too late.


  ```js
  import * as fs from fs; // importing the named exports as an object
  ```


This looks great. Other alternatives I thought about in response included `import { * } as fs from 
fs` and `import module fs from fs`, but upon consideration the brevity of 
yours wins.

I just hope we can do better documenting it, this time around, and fixing the 
many transpilers with their confusing semantics.


Finalize the normative spec, see what happens.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: ModuleImport

2014-06-19 Thread Brendan Eich

Domenic Denicola wrote:

The transitional era will be a particularly vulnerable time for TC39's module 
design, however: as long as people are using transpilers, there's an 
opportunity for a particularly well-crafted, documented, and supported 
transpiler to give alternate semantics grounded in the community's preferred 
model, and win over enough of an audience to bleed the life out of TC39's 
modules.


You're doing a disservice to everyone here by implying that such a 
transpiler could trump native modules as implemented per the normative 
ES6 spec in Chakra, JSC, SpiderMonkey, and V8.


Idle speculations are not even worth betting on, but filling es-discuss 
with tendentious idle speculations is worse. Cut it out.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss