nate to its caller, the relationship between them being similar to that between a called and
a calling routine. A different control discipline is implemented by symmetric coroutine
facilities, which provide a single transfer operation for switching control to the indicated
coroutine. Because symmetric coroutines are capable of passing control between them-
selves, they are said to operate at the same hierarchical level. The following arguments
justify why Lua offers asymmetric coroutines, instead of providing symmetric facilities
or both mechanisms.
It has been argued that symmetric and asymmetric coroutines have no equiva-
lent power, and that general-purpose coroutine facilities should provide both constructs
[Marlin, 1980, Pauli and Soffa, 1980]. However, it is easy to demonstrate that symmetric
coroutines can be expressed by asymmetric facilities (see Appendix A). Therefore, no
expressive power is lost if only asymmetric coroutines are provided. (Actually, imple-
menting asymmetric coroutines on top of symmetric facilities is equally simple). Imple-
menting both abstractions only complicates the semantics of the language. In Simula, for
instance, the introduction of semicoroutines led to problems in understanding the details
of coroutine sequencing, and several efforts to describe the semantics of Simula corou-
tines were shown to be inconsistent [Marlin, 1980].
Since expressive power is not an issue, preserving two of the main characteris-
tics of the Lua, simplicity and portability, constitutes the main reason for implementing
asymmetric facilities. Most programmers nowadays have already been exposed to the
the concept of a thread, which, like a coroutine, represents a line of execution that can
be interrupted and later resumed at the point it was suspended. Nevertheless, coroutine
mechanisms are frequently described as difficult to understand. In fact, handling ex-
plicitly the sequencing between symmetric coroutines is not an easy task, and requires
a considerable effort from the programmer. Even experienced programmers may have
difficulties in understanding the control flow of a program that employs a moderate num-
ber of symmetric coroutines. On the other hand, asymmetric coroutines truly behave like
routines, in the sense that control is always transfered back to their callers. Since even
novice programmers are familiar with the concept of a routine, control sequencing with
asymmetric coroutines seems much simpler to manage and understand, besides allowing
the development of more structured programs. A similar argument is used in proposals
of partial continuations that, like asymmetrical coroutines, can be composed like regular
functions [Danvy and Filinski, 1990, Queinnec and Serpette, 1991, Hieb et al., 1994].
The other motivation for implementing asymmetric coroutines was the need to
preserve Lua’s ease of integration with its host language (C) and also its portability. Lua
and C code can freely call each other; therefore, an application can create a chain of nested
function calls wherein the languages are interleaved. Implementing a symmetric facility in
this scenario imposes the preservation of C state when a Lua coroutine is suspended. This
preservation is only possible if a coroutine facility is also provided for C; but a portable
implementation of coroutines for C cannot be written. On the other hand, we do not need
coroutine facilities in C to support Lua asymmetric coroutines; all that is necessary is a
restriction that a coroutine cannot yield while there is a C function in that coroutine stack.