|
|
|
|
|
by gpderetta
1358 days ago
|
|
So, you didn't give the explanation of what your snippet is supposed to do but, assuming that await returns control to f (as that the only thing that can happen with stackless coroutines) the equivalent in go would be to spawn a goroutine when calling g (pseudocode as I know approximately zero go): fn f() { var v1 = ..., var v2 = ...; go g(v2); }
fn g(v2) { /* do something with v2 */ }
There is no await as they are implicit in go. The coroutine spawned in f will only need to capture v2. I could make similar examples in cilk++, lua, or really any language with stackful coroutines.Of course if you do not spawn a coroutine in f and it is instead part of another coroutine, v1 might be captured (unless the compiler identifies it as dead and reuses the stack slot, say, for v2). But to express the same with stackless coroutines you need to make f also a coroutine which will end up capturing v1 if live across the call. Am I missing something? |
|
No, await is a context switch of some kind. In a stackful implementation the stack is switched to another thread at that point (say for an I/O wait), in an async implementation, the point after await is resumed with the live variables needed for the remainder of the program because it will be passed an explicit continuation.
> Of course if you do not spawn a coroutine in f and it is instead part of another coroutine, v1 might be captured (unless the compiler identifies it as dead and reuses the stack slot, say, for v2). But to express the same with stackless coroutines you need to make f also a coroutine which will end up capturing v1 if live across the call.
Yes, the idea is that v1 is not live, and existing stackful implementations will capture it regardless, where an async written program written in CPS form will not capture it. As I initially said the state captured by the latter is a strict subset of the former.