

Lua-Style Coroutines in C++ - mfichman
http://mfichman.blogspot.com/2011/05/lua-style-coroutines-in-c.html

======
gorset
Wouldn't "create", "getcurrent" and "switch" be better primitives for
coroutines [0]?

Having a concept of caller and callee complicates the maintenance of a large
number of "concurrent" coroutines that does different things, and "yield" can
be implemented by just using a global variable.

[0]:
[http://pypy.readthedocs.org/en/latest/stackless.html#corouti...](http://pypy.readthedocs.org/en/latest/stackless.html#coroutines)

~~~
pygy_
Lua uses asymmetric coroutines, you're describing the symmetric variety.

From _Programming in Lua_ [1] by R. Ierusalimschy

 _For those that already know something about coroutines, it is important to
clarify some concepts before we go on. Lua offers what I call asymmetric
coroutines. That means that it has a function to suspend the execution of a
coroutine and a different function to resume a suspended coroutine. Some other
languages offer symmetric coroutines, where there is only one function to
transfer control from any coroutine to another.

Some people call asymmetric coroutine semi-coroutines (because they are not
symmetrical, they are not really co). However, other people use the same term
semi-coroutine to denote a restricted implementation of coroutines, where a
coroutine can only suspend its execution when it is not inside any auxiliary
function, that is, when it has no pending calls in its control stack. In other
words, only the main body of such semi-coroutines can yield. A generator in
Python is an example of this meaning of semi-coroutines.

Unlike the difference between symmetric and asymmetric coroutines, the
difference between coroutines and generators (as presented in Python) is a
deep one; generators are simply not powerful enough to implement several
interesting constructions that we can write with true coroutines. Lua offers
true, asymmetric coroutines. Those that prefer symmetric coroutines can
implement them on top of the asymmetric facilities of Lua. It is an easy task.
(Basically, each transfer does a yield followed by a resume.) _

[1] <http://www.lua.org/pil/index.html>, <http://www.lua.org/pil/9.1.html>

~~~
silentbicycle
This short paper [1] has an excellent description of Lua's coroutines, why
they're useful, how they compare to continuations, etc. (In short, they are
isomorphic to one-shot continuations, but a bit more convenient for many
common use cases.) It expands on the paper linked in the post.

1: <http://www.inf.puc-rio.br/~roberto/docs/MCC15-04.pdf>

------
aliguori
Most C++ implementations throw their hands up at
setjmp/longjmp/setcontext/makecontext.

Even if it appears to work, it's a dangerous set of routines to use in C++.

~~~
pja
Yeah, this is going to mix very badly with exceptions.

Also, a little rootling around on the web reveals the following statement in
IBM's z/OS docs:

"Do not issue getcontext() in a C++ constructor or destructor, since the saved
context would not be usable in a subsequent setcontext() or swapcontext()
after the constructor or destructor returns."

