|
|
|
|
|
by xg15
861 days ago
|
|
I think now I get why I find Python's async/await semantics (asyncio) so much more convoluted than Javascript's. Javascript starts with simple callbacks. Those indeed have no stack, only a shallow list of local variables as state. Then async/await is modelled as a relatively straightforward syntactic sugar on top of that: An await call is still just a callback behind the scenes; if one async function awaits another async function, you get something that looks like a stack, but is really just a chain of callbacks. In contrast, Python starts with coroutines, which do have a stack, then models async/await by surrounding them with a scheduling runtime. Unfortunately, for async code to be useful, you still need support for callbacks, so you end up with both: an await call represents a mix of suspended coroutine stacks and callback chains, which can be much more complicated to reason about. |
|
But callbacks and callback-based async/await force you to compress application state better, so you will get better performance out of that. No need for `call/cc` style continuations, just light-weight continuations, but this is mainly a mirage because in the callback model you do in fact have continuations, it's just that the continuation is only ever "the next step in processing this thing" rather than "the whole stack".
That is, with hand-coded CPS you get a very shallow stack to capture in continuations, so the continuations are very cheap.