Re: await on synchronous functions
I think we're confusing two different cases here: 1) usage of `await` in the body of a function that is not itself marked as `async` 2) usage of `await f()` where `f` is not marked as `async`. 1 is easy to mark as an early error (and should be imo). 2, not so much (and is what Mark was asking?) -c On Fri, Jul 17, 2015 at 12:30 PM, Ben Newman benja...@cs.stanford.edu wrote: If we stick with the rule that await is only regarded as a keyword if it appears in the body of an async function, then await x without async is simply a syntax error, and we can avoid having to answer this question! That said, perhaps a more natural way of handling wayward await expressions is to treat them as referring to the closest enclosing async function on the call stack (not necessarily the immediate enclosing function), throwing an exception if there is no async function on the stack. Then any await expression would delay the resolution of the Promise returned by whatever async function is currently executing. The same-function-body syntax restriction is a special case of that more general model (and notably easier to implement by transpiling to generators!). Generalizing async/await in this way turns out to be equivalent to introducing coroutines into the language, and while I would love to see that happen one day (it would greatly simplify writing parallel forEach loops, for example), it would require substantial changes to the execution model of the language. Here are some slides from a talk I gave earlier this year about the benefits and pitfalls of coroutines, in case you're interested: http://benjamn.github.io/goto2015-talk On Fri, Jul 17, 2015 at 11:35 AM Andrea Giammarchi andrea.giammar...@gmail.com wrote: Think about a large program where you refactor a single async function to no longer be async did that ever happened in the history of logic? I am actually curious to understand a single valid case where that would be a solution to any problem. Apologies if I can't see your point but we've been talking about Promise must Promise so much this answer was absolutely unexpected. Thanks for any sort of clarification On Fri, Jul 17, 2015 at 7:27 PM, Tom Van Cutsem tomvc...@gmail.com wrote: 2015-07-17 19:41 GMT+02:00 Andrea Giammarchi andrea.giammar...@gmail.com: If I might, if there's one thing that has never particularly shone in JS, that is consistency. I see only two possibilities here: 1) it throws with non Promises 2) it Promisify anything that's not a Promise as if it was a `Promise.resolve(1)` ... but since there's too much magic in the second point, I'd rather stick with the first one. I would be highly in favor of (2). Think about a large program where you refactor a single async function to no longer be async. Then I see no reason why I should be forced to refactor all of its callers to remove the await keyword. Going from sync to async requires refactoring because you're introducing new potential interleaving hazards, but any code that is already prepared to work with async functions (or promises in general) should work equally fine on immediately resolved promises. regards, Tom Just my quick thoughts Best Regards On Fri, Jul 17, 2015 at 6:33 PM, Kevin Smith zenpars...@gmail.com wrote: I know the spec for this isn't finalized, but what is the current direction for the behaviour when await is used on a function that is not marked async and doesn't return a Promise? Should it run immediately or wait for the next turn of the event loop? More generally, the question is: what should await do for non-promises? await 1; Should it force a job to be queued? ___ 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 ___ 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Removal of WeakMap/WeakSet clear
On Thu, Nov 27, 2014 at 10:40 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: This is the end of my assumed inverted WC design and why I assert that a clear method is incompatible with it. Couldn't this be solved by adding a little state (a monotonically increasing 'generation' counter) to the WC? Then, something like this: ```js WC.prototype.clear = function() { this.generation ++; } WC.prototype.has = function(k) { var slot = getWCSlot(k, this); return slot slot.generation == this.generation; }; WC.prototype.set = function(k, v) { var slot = getWCSlot(k, this); if (slot) { // update the slot's information (including generation) slot.generation = this.generation; slot.value = v; } else { k[@@weakContainers][this] = { generation: this.generation, value: v }; } }; WC.prototype.get = function(k) { var slot = getWCSlot(k, this); if (!slot) return undefined; if (slot.generation != this.generation) { // purge the key's slot for this weakmap delete k[@@weakContainers][this]; return undefined; } return slot.value; }; ``` Then clear()'s description can be changed to (if it wasn't this already) simply: There is no way to retrieve values corresponding to keys added prior to the clear() ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Removal of WeakMap/WeakSet clear
A more compact implementation occurred to me during my commute: just have an internal slot in the WC that it uses when looking up values, instead of the WC reference itself. This has the downside of not being able to purge old slots on calls to has/get, but removes the possibility of overflow (if 'generation' is a uint32, e.g) ```js WC.prototype.clear = function() { this.[[WCIdentity]] = new object(); } WC.prototype.has = function(k) { var slot = GetWCSlot(k, this.[[WCIdentity]]); return slot !== undefined; }; WC.prototype.set = function(k,v) { var slot = GetWCSlot(k, this.[[WCIdentity]]); if (!slot) slot = CreateWCSlot(k, this.[[WCIdentity]]); slot.value = v; }; WC.prototype.get = function(k) { var slot = GetWCSlot(k, this.[[WCIdentity]]); return slot slot.value; }; ``` On Wed, Dec 3, 2014 at 9:20 AM, Chris Toshok tos...@gmail.com wrote: On Thu, Nov 27, 2014 at 10:40 AM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: This is the end of my assumed inverted WC design and why I assert that a clear method is incompatible with it. Couldn't this be solved by adding a little state (a monotonically increasing 'generation' counter) to the WC? Then, something like this: ```js WC.prototype.clear = function() { this.generation ++; } WC.prototype.has = function(k) { var slot = getWCSlot(k, this); return slot slot.generation == this.generation; }; WC.prototype.set = function(k, v) { var slot = getWCSlot(k, this); if (slot) { // update the slot's information (including generation) slot.generation = this.generation; slot.value = v; } else { k[@@weakContainers][this] = { generation: this.generation, value: v }; } }; WC.prototype.get = function(k) { var slot = getWCSlot(k, this); if (!slot) return undefined; if (slot.generation != this.generation) { // purge the key's slot for this weakmap delete k[@@weakContainers][this]; return undefined; } return slot.value; }; ``` Then clear()'s description can be changed to (if it wasn't this already) simply: There is no way to retrieve values corresponding to keys added prior to the clear() ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ModuleImport
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
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: ModuleImport
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: ModuleImport
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: Re: Rationale for dropping ModuleImport syntax?
On Thu, Jun 12, 2014 at 3:46 AM, Brian Di Palma off...@gmail.com wrote: Is there anything preventing the addition of a ModuleImport like affordance at a later stage (e.g. ES7)? ModuleImport is the only way (in syntax) to achieve CommonJS `require` behavior on the consumer-side when a module author exclusively uses multiple exports. Its lack will force existing module maintainers to export as small a set as possible - likely either a single identifier - so that they can service the existing identifier-as-namespace convention CommonJS forces. Given that there's no real syntactic difference between single identifier export and default export, I would imagine default export would win since then you get: `import _ from 'underscore'` instead of import { _ } from 'underscore'`. Related to some other comments made in this thread, I think static verification errors are a great idea. I'd also like to echo the comments that ES6 modules seem well designed, looking forward to native implementations. I definitely agree. I think the semantics and specification are awesome. And having syntax at all is *huge* for tooling and aot/static compilers. The ModuleImport syntax can be bikeshedded until the cows come home. It's not important (to me). What's important is that there is syntax to get at its functionality, not imperative code. IMO the only real issue is the tight coupling between syntax used to import and syntax used to export. Why as a module consumer should the module author's choice dictate which syntax I'm forced to use? And why as a module author should the syntax my users want to use dictate how I have to export my module? If syntaxes were decoupled, ModuleImport could go away and we wouldn't lose the functionality, it would simply be `import _ from 'underscore'`. I don't think it's outlandish, the possibility that a large enough portion of the community will decide on a single import syntax as best, and network effects will result in it going from best to only. -c ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Rationale for dropping ModuleImport syntax?
Pirouette also has many exports per module for its bindings: E.g. https://github.com/toshok/pirouette/blob/master/bindings/uikit.js. I use both import-{}-from (with many imported bindings) and module-from forms, tending toward the former in framework code and the latter in application code. The fact that the both forms can be accommodated from a single export form is the key for me. -c On Jun 9, 2014, at 8:36 AM, Caridy Patino car...@gmail.com wrote: My perspective here is that there are not too many modules (in nodejs) that rely on more than a handful of exports from a particular module, we are actively working on validating this using esprima in a large set of npm modules. If this is true, we should be just fine with specific imports, and for the edge cases, an imperative form should be sufficient. For now, I will ask you all to try to find a modules that are using too many exported methods from one of its imported modules, you will be suprise how hard it is too find those. /caridy On Mon, Jun 9, 2014 at 11:27 AM, Axel Rauschmayer a...@rauschma.de wrote: As an aside, it is yet to be seen whether the default export thing is the best way, or the bad part itself. We don't have the real world experience yet to answer that. I’d even argue that they led to the predicament that we are currently in. If the default export didn’t look like “the module”, things would, in my opinion, be easier to understand: ```js import _ from Underscore; import { flatten, union } from Underscore; import default someFunction from single_function_module; ``` -- 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Rationale for dropping ModuleImport syntax?
That particular use of module-from is a little special. @objc_internal is a native module. Once ejs supports enumerating multiple exports from native modules I'll be switching that to an import-{}-from. An example of use would be my toy test applications that consume the modules: https://github.com/toshok/echo-js/blob/master/test/osx-test/helloosx.js This uses the import-{}-from syntax and as you can see it's getting rather long for appkit (and it only has a window, a button, and a table view). In my other toy apps I've switched exclusively to module-from to keep things from getting out of hand while I work. I thought I'd also added an iOS test to the git repo, but apparently I haven't - will rectify today. I would also suggest that supporting both forms allows for better early prototyping (module-from) when you don't know exactly what you'll be pulling in, with the optional upgrade to potentially faster (definitely faster in ejs currently) import-{}-from form later when your code matures, all while maintaining easy static checking. On Jun 9, 2014, at 9:26 AM, Caridy Patino car...@gmail.com wrote: Chris, the number of exports is not relevant, and in fact, there is no way to export all members in one go, which aligns well with the proposal to remove the way to import an object with all members. check the consumers of the `uikit` module, and count how many of those exported methods are used in a single module. In fact, this repo is consistent with what we have been saying. If you look at https://github.com/toshok/pirouette/blob/master/bindings/objc.js, it uses `module objc_internal from '@objc_internal';`, then it uses 5 methods exported by that module, which should not be a pain to declare them explicit as imports. On Mon, Jun 9, 2014 at 12:18 PM, Chris Toshok tos...@gmail.com wrote: Pirouette also has many exports per module for its bindings: E.g. https://github.com/toshok/pirouette/blob/master/bindings/uikit.js. I use both import-{}-from (with many imported bindings) and module-from forms, tending toward the former in framework code and the latter in application code. The fact that the both forms can be accommodated from a single export form is the key for me. -c On Jun 9, 2014, at 8:36 AM, Caridy Patino car...@gmail.com wrote: My perspective here is that there are not too many modules (in nodejs) that rely on more than a handful of exports from a particular module, we are actively working on validating this using esprima in a large set of npm modules. If this is true, we should be just fine with specific imports, and for the edge cases, an imperative form should be sufficient. For now, I will ask you all to try to find a modules that are using too many exported methods from one of its imported modules, you will be suprise how hard it is too find those. /caridy On Mon, Jun 9, 2014 at 11:27 AM, Axel Rauschmayer a...@rauschma.de wrote: As an aside, it is yet to be seen whether the default export thing is the best way, or the bad part itself. We don't have the real world experience yet to answer that. I’d even argue that they led to the predicament that we are currently in. If the default export didn’t look like “the module”, things would, in my opinion, be easier to understand: ```js import _ from Underscore; import { flatten, union } from Underscore; import default someFunction from single_function_module; ``` -- 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 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss