Re: Fwd: Reason why generators do not have references to themselves?
[replying to a message you sent off-list, hope it is ok. /be] Brendan Eich wrote: Bradley Meck wrote: Perhaps, but I am still a bit concerned functionality wise that I do not have a clean way to force the `new generator()` piece of code to be inside of the generator. I think you've gone down a bad path. Even without task.js, couldn't you put the promises .then'ing in the generator schedule, Sorry, last word should be scheduler above. The await syntax needs a scheduler behind the scenes, and task.js has one. The scheduler duck-types the result of yield expressions in the generator, and if it is a promise, arranges to .next the generator when the promise is fulfilled, or .throw at it when rejected. Instead you compile await in a way that expands the promise .then'ing inline in the generator body, requiring a ref to the generator in a closure, for use from function expressions passed to .then and .catch. Is this more clear? /be instead of requiring each generator to open-code the .then/.catches, which in turn requires you to have a ref to the generator? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fwd: Reason why generators do not have references to themselves?
Perhaps, but I am still a bit concerned functionality wise that I do not have a clean way to force the `new generator()` piece of code to be inside of the generator. I cannot easily convert it akin to how new can be caught: ``` function* generatorFn() { if (this instanceof generatorFn) { return new generatorFn // does not work } } ``` Since it will be wrapped. So I guess a throw trap is the only way: ``` function* generatorFn() { if (this instanceof generatorFn) { throw new Error(This must be called with new); } } ``` But even then we are not able to tell if the generator is in standbyStartup or the currently active `generatorFn`. Does the lack of being able to test that make sense? On Fri, Jan 24, 2014 at 8:40 AM, Domenic Denicola dome...@domenicdenicola.com wrote: It seems like this is largely a matter of personal aesthetics (feels dirty, hacky, etc.) but nothing is wrong or even hard functionally. Furthermore given the prevalence of code out there that uses such hacks without compunction, it seems that your aesthetics are not shared by most. Maybe the easiest path toward resolving this, um, problem?, is simply adjusting your preferences to recognize this kind of code for the beautiful code it is. On Jan 24, 2014, at 4:07, Bradley Meck bradley.m...@gmail.com wrote: Taking note with async polyfills and syntax for a minute. I spent a fair amount of time actually writing the spec of my intent/goal after getting some thought and working things through in my head (varies slightly from old 2011 await): https://gist.github.com/bmeck/674e21f40fe6e9ce6304#file-close-but-no-cigar-sweet-js-L6 I can get really close with sweet.js (see gist), but as such I still have to use new when invoking the generator function which feels dirty in my mind. Perhaps if I did some crazy code transforms to test if the generator function was using await it would work. That would require me to wrap it similar to how task.js and all the other libraries IRC bombarded me with. I think it very strange that they all: 1. make a promise that will be returned (finalPromise) 2. call the generator and hook it up to the promise 3. don't appear to have a clean way to make the generator continue without resolving finalPromise and without forcing the generator to completion * bluebird's Promise.coroutine comes closeish but still needs to run the generator to completion It seems that every approach I am taking gets me slightly closer, but none are a clean way for a generator to iterate itself without some hacky argument passing and wrapping. PS. Sorry about the horrifying sweet.js macro, but it is functional enough in Chrome with experimental JS from what I tried out. On Fri, Jan 24, 2014 at 2:18 AM, David Herman dher...@mozilla.com wrote: On Jan 23, 2014, at 4:49 PM, Brendan Eich bren...@mozilla.com wrote: Domenic Denicola wrote: Task.js is still on JavaScript1.8, and is not ES6-compatible. It won't work with modern browsers, or with Regenerator. Fork and fix, should be easy. I expect a PR would be accepted in due course. SpiderMonkey seems to have ES6 generator support somewhat there (thanks to Andy Wingo), should be all there soon enough. Working on it lately, actually. And using regenerator for the tests (\o/)! Also drastically simplifying the library since the customizable scheduler stuff, while kind of neat, is probably less compelling than a minimal library. Down to under 150 lines, unminified with comments, and still shrinking... Dave ___ 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: Fwd: Reason why generators do not have references to themselves?
Bradley Meck wrote: Perhaps, but I am still a bit concerned functionality wise that I do not have a clean way to force the `new generator()` piece of code to be inside of the generator. I think you've gone down a bad path. Even without task.js, couldn't you put the promises .then'ing in the generator schedule, instead of requiring each generator to open-code the .then/.catches, which in turn requires you to have a ref to the generator? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Fwd: Reason why generators do not have references to themselves?
Is that true even though then should fire after the generator unwinds its stack? I am using regenerator right now while playing with this stuff. On Jan 23, 2014 5:43 PM, Brendan Eich bren...@mozilla.com wrote: Andrea Giammarchi wrote: arguments.callee.caller would have done that /trolling /but-actually-not-so-much No, Bradley wants the generator-iterator (what ES6 draft calls a Generator), not the generator function (GeneratorFunction). Any .callee would have to be a function, so a GeneratorFunction. But the gist'ed example won't work: function* doLogin_() { try { /* START ASYNC TRANSPILE */ login(req).then(function (session) { gen.next(session); You can't next an active generator. Instead, the trick is to avoid promises inside the generator function. Put them on the outside (and backstage) as task.js does. http://taskjs.org/. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fwd: Reason why generators do not have references to themselves?
Bradley Meck wrote: Is that true even though then should fire after the generator unwinds its stack? True if .then always runs in a later turn -- sorry. Still, my point stands: you are not using task.js-like scheduler/combinator approach for an apples-to-apples comparison with await. If you do, then we're down to the obligation of a task.js download, and some syntactic sugar. // assume req in scope spawn(function*() { try { var session = yieldlogin(req); // wait until the promise resolves gotoProfile(session); } catch (e) { printError(e); gotoLogin(); } // implicit return undefined }); BTW, in ES7, no use await; will be needed ;-). If you want to control when the task starts, you'd use new Task. If you want to send req, you'd control starting via t = new Task(function*(){...}) and call t.next(req). Hope this is all clear from http://taskjs.org/ and the code. I am using regenerator right now while playing with this stuff. Cool -- can you try task.js? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Fwd: Reason why generators do not have references to themselves?
Still, my point stands: you are not using task.js-like scheduler/combinator approach for an apples-to-apples comparison with await. If you do, then we're down to the obligation of a task.js download, and some syntactic sugar. see comments in gist, adding a library also has some stuff with source maps that I am not too keen on in particular. I can use libraries to simplify many things / manage code, but doing similar tasks without using a library seems more in line w/ my original question (which has been answered). Either way, for now it seems like generator-iterators won't have references to themselves and I can just wrap it. Allan: an interesting idea that does simplify things, updating gist. Still using a wrapper since even w/ new the generator returns a generator instance (otherwise I could use instanceof checks). Note: cleaned up gist somewhat in general / simplified On Thu, Jan 23, 2014 at 6:43 PM, Brendan Eich bren...@mozilla.com wrote: Bradley Meck wrote: Is that true even though then should fire after the generator unwinds its stack? True if .then always runs in a later turn -- sorry. Still, my point stands: you are not using task.js-like scheduler/combinator approach for an apples-to-apples comparison with await. If you do, then we're down to the obligation of a task.js download, and some syntactic sugar. // assume req in scope spawn(function*() { try { var session = yieldlogin(req); // wait until the promise resolves gotoProfile(session); } catch (e) { printError(e); gotoLogin(); } // implicit return undefined }); BTW, in ES7, no use await; will be needed ;-). If you want to control when the task starts, you'd use new Task. If you want to send req, you'd control starting via t = new Task(function*(){...}) and call t.next(req). Hope this is all clear from http://taskjs.org/ and the code. I am using regenerator right now while playing with this stuff. Cool -- can you try task.js? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss