Last active
August 29, 2015 14:27
-
-
Save dyoder/f598f703d9644e7627a3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15:28 < david> Dan, are you around? | |
15:32 < david> Well, actually this doesn't require anything dramatic, haha. | |
15:34 < david> I know why Tonicdev cannot use Fairmont. It lets you use the await operator from ES7 to wait on promises, but it doesn't know anything about generators. It's running Node 12 without the Harmony flag, so it's ES5 JS with that await functionality baked in because it makes things so much easier. | |
15:36 < david> I'm curious if you're interested in generators in Fairmont's future, since ES7 has asynchronous functions and this "await" thing. Although, does CoffeeScript support those ES7 features? | |
15:44 < david> It looks like work in CS is still pending, but being actively considered. https://github.com/jashkenas/coffeescript/pull/3757 | |
15:49 < david> It's kinda weird... await and yield are similar and both need an outer, calling function. But yield's outer function must be a generator. Is one preferred over the other? | |
18:21 < lance> tom: cool! | |
19:24 < dan> david: it's a bit of a mess. | |
19:25 < dan> semi-coroutines with generator functions has a bit of overhead | |
19:25 < dan> so async-await is intended to build that into the JS engines | |
19:26 < dan> under the covers, i think await converts into a yield and a generator function | |
19:27 < dan> but it can't actually be a generator function, so a different keyword is needed | |
19:27 < dan> i'm not really certain why async couldn't have been introduced instead, just as we use it in fairmont | |
19:28 < dan> without the use of await (using just yield) | |
19:28 < dan> but i'm sure there's a very good reason for that | |
19:28 < dan> if i spent enough time studying it, that would likely become obvious | |
19:30 < dan> but once you stipulate that async can't operate on a generator function, you then need a different keyword | |
19:30 < dan> since yield can only happen from within a generator function | |
19:31 < dan> it's a little bit unfortunate because all our code is based on ES6 and using generators as semi-coroutines | |
19:31 < dan> for performance reasons i've rewritten some of that code to use normal functions and promises directly | |
19:32 < dan> but it's possible that we will eventually want to use async-await | |
19:32 < dan> or, we should use traceur/babel now and use async-await, presuming the generated code is just functions and promises | |
19:33 < dan> but that brings us to the issue you raised about CS support, which right now, is in the very early stages | |
19:33 < david> Okay. | |
19:33 < dan> jashkenas does not appear to have endorsed any approach | |
19:33 < david> yeah, incorporating babel into the build process seems like it's going to happen at some point. | |
19:34 < david> Well, it sounds like the function* yield vs async await should be a blog post, haha. | |
19:36 < david> I would hope that their reason is very strong, because it seems confusing at best and dangerous at worst to have these parallel approaches to asynchronous methods. | |
19:37 < david> Does it have to do with how ES6 "native" promises are specified? Are they somehow inferior to one produced by a library like when or bluebird? | |
19:37 < dan> david: no i think it is purely a performance thing | |
19:38 < dan> coroutines with generators requires a controller/manager function, that takes the yield values and then returns control back to the function | |
19:38 < dan> when they resolve (if the value was a promise) | |
19:39 < dan> this ping-pong is costly. in my benchmarks, it was like an order of magnitude slower. | |
19:40 < dan> however, the generator plumbing is necessary to support async-await, because it think what that does is take the manager function and compile that into the JS engine | |
19:40 < dan> (that is, it's written directly in C) | |
19:41 < dan> and the async modifier tells the compiler to treat the function much like a generator, but probably optimized somewhat to work with the manager function | |
19:41 < david> hmm.. And they can't do that with ES6 generators because they might not be returning a promise? | |
19:41 < dan> there won't be anything confusing about it because async-await will be THE way to do what we're currently doing with async (as a wrapper function) and yield | |
19:42 < dan> no. it's just a performance thing. if you know a generator is being used as a coroutine, you can compile it differently | |
19:42 < david> Oh. Okay | |
19:42 < dan> you can optimize for that case, especially since the controller function is already in C | |
19:43 < dan> what we're doing now is wrapping the generator in a JavaScript controller function (that's what async does) | |
19:43 < dan> but that's also why it's so slow | |
19:43 < dan> if the controller function is in C and the generator function could be optimized to communicate with that C function, it could potentially be much faster | |
19:44 < dan> maybe as fast as just hand-coding promise-logic | |
19:45 < david> Okay. Cool. I guess I was so excited by ES6's avoidance of callbacks that I didn't realize it ran that much more slowly. | |
19:48 < dan> david: most of the time it's not a big deal | |
19:49 < dan> but for example in fairmont's filter functions (map, select, reject, ...) i have taken out most of the generator-based code and replaced it with promises-based logic | |
19:50 < dan> because they're part of a general purpose library | |
19:50 < dan> for application-level code, though, you can do everything using generators and optimize out the stuff where it's problematic | |
19:51 < dan> keep in mind that, if you're using coroutines like that, it's probably because there's an I/O operation involved which is several orders of magnitude slower than the ping-ponging of manager functions | |
19:51 < dan> the path laid out in ES6 is very clever and very much in keeping with eich's approach to this stuff | |
19:52 < dan> first, make coroutines _possible_; second, (in ES7) offer an optimized implementation | |
19:52 < dan> optimized/standardized | |
19:52 < dan> (since every promise library has their own version of a controller function) | |
19:53 < dan> (so you can inadvertantly wind up with several controller functions in your app for no good reason other than one library did it one way and another library did it another way) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment