Coroutines are
computer program
A computer program is a sequence or set of instructions in a programming language for a computer to Execution (computing), execute. It is one component of software, which also includes software documentation, documentation and other intangibl ...
components that allow execution to be suspended and resumed, generalizing
subroutines for
cooperative multitasking. Coroutines are well-suited for implementing familiar program components such as
cooperative tasks,
exceptions,
event loops,
iterators,
infinite lists and
pipes.
They have been described as "functions whose execution you can pause".
Melvin Conway coined the term ''coroutine'' in 1958 when he applied it to the construction of an
assembly program.
The first published explanation of the coroutine appeared later, in 1963.
Definition and types
There is no single precise definition of coroutine. In 1980 Christopher D. Marlin summarized two widely-acknowledged fundamental characteristics of a coroutine:
# the values of data local to a coroutine persist between successive calls;
# the execution of a coroutine is suspended as control leaves it, only to carry on where it left off when control re-enters the coroutine at some later stage.
Besides that, a coroutine implementation has 3 features:
# the control-transfer mechanism. ''Asymmetric coroutines'' usually provide keywords like
yield
and
resume
. Programmers cannot freely choose which frame to yield to. The runtime only yields to the nearest caller of the current coroutine. On the other hand, in ''symmetric coroutines'', programmers must specify a yield destination.
# whether coroutines are provided in the language as
first-class objects, which can be freely manipulated by the programmer, or as constrained constructs;
# whether a coroutine is able to suspend its execution from within nested function calls. Such a coroutine is a ''stackful coroutine''. One to the contrary is called ''stackless coroutines'', where unless marked as coroutine, a regular function can't use the keyword
yield
.
The paper "Revisiting Coroutines" published in 2009 proposed term ''full coroutine'' to denote one that supports first-class coroutine and is stackful. Full Coroutines deserve their own name in that they have the same
expressive power as one-shot
continuations and delimited continuations. Full coroutines are either symmetric or asymmetric. Importantly, whether a coroutine is symmetric or asymmetric has no bearing on how expressive it can be as they are equally as expressive, though full coroutines are more expressive than non-full coroutines. While their expressive power is the same, asymmetrical coroutines more closely resemble routine based control structures in the sense that control is always passed back to the invoker, which programmers may find more familiar.
Comparison with
Subroutines
Subroutines are special cases of coroutines.
When subroutines are invoked, execution begins at the start, and once a subroutine exits, it is finished; an instance of a subroutine only returns once, and does not hold state between invocations. By contrast, coroutines can exit by calling other coroutines, which may later return to the point where they were invoked in the original coroutine; from the coroutine's point of view, it is not exiting but calling another coroutine.
Thus, a coroutine instance holds state, and varies between invocations; there can be multiple instances of a given coroutine at once. The difference between calling another coroutine by means of
"yielding" to it and simply calling another routine (which then, also, would return to the original point), is that the relationship between two coroutines which yield to each other is not that of caller-callee, but instead symmetric.
Any subroutine can be translated to a coroutine which does not call ''yield''.
Here is a simple example of how coroutines can be useful. Suppose you have a consumer-producer relationship where one routine creates items and adds them to a queue and another removes items from the queue and uses them. For reasons of efficiency, you want to add and remove several items at once. The code might look like this:
''var'' q := new queue
coroutine produce
loop
while q is not full
create some new items
add the items to q
yield to consume
coroutine consume
loop
while q is not empty
remove some items from q
use the items
yield to produce
call produce
The queue is then completely filled or emptied before yielding control to the other coroutine using the ''yield'' command. The further coroutines calls are starting right after the ''yield'', in the outer coroutine loop.
Although this example is often used as an introduction to
multithreading, two threads are not needed for this: the ''yield'' statement can be implemented by a jump directly from one routine into the other.
Threads
Coroutines are very similar to
threads. However, coroutines are
cooperatively multitasked, whereas threads are typically
preemptively multitasked. Coroutines provide
concurrency, because they allow tasks to be performed out of order or in a changeable order, without changing the overall outcome, but they do not provide
parallelism, because they do not execute multiple tasks simultaneously. The advantages of coroutines over threads are that they may be used in a
hard-realtime context (
switching between coroutines need not involve any
system calls or any
blocking calls whatsoever), there is no need for synchronization primitives such as
mutexes, semaphores, etc. in order to guard
critical sections, and there is no need for support from the operating system.
It is possible to implement coroutines using preemptively-scheduled threads, in a way that will be transparent to the calling code, but some of the advantages (particularly the suitability for hard-realtime operation and relative cheapness of switching between them) will be lost.
Generators
Generators, also known as semicoroutines,
are a subset of coroutines. Specifically, while both can yield multiple times, suspending their execution and allowing re-entry at multiple entry points, they differ in coroutines' ability to control where execution continues immediately after they yield, while generators cannot, instead transferring control back to the generator's caller. That is, since generators are primarily used to simplify the writing of
iterators, the
yield
statement in a generator does not specify a coroutine to jump to, but rather passes a value back to a parent routine.
However, it is still possible to implement coroutines on top of a generator facility, with the aid of a top-level dispatcher routine (a
trampoline, essentially) that passes control explicitly to child generators identified by tokens passed back from the generators:
''var'' q := new queue
generator produce
loop
while q is not full
create some new items
add the items to q
yield
generator consume
loop
while q is not empty
remove some items from q
use the items
yield
subroutine dispatcher
''var'' d := new dictionary(generator → iterator)
d
roduce:= start consume
d
onsume:= start produce
''var'' current := produce
loop
call current
current := next d
urrent
call dispatcher
A number of implementations of coroutines for languages with generator support but no native coroutines (e.g. Python
before 2.5) use this or a similar model.
Mutual recursion
Using coroutines for state machines or concurrency is similar to using
mutual recursion with
tail calls, as in both cases the control changes to a different one of a set of routines. However, coroutines are more flexible and generally more efficient. Since coroutines yield rather than return, and then resume execution rather than restarting from the beginning, they are able to hold state, both variables (as in a closure) and execution point, and yields are not limited to being in tail position; mutually recursive subroutines must either use shared variables or pass state as parameters. Further, each mutually recursive call of a subroutine requires a new stack frame (unless
tail call elimination is implemented), while passing control between coroutines uses the existing contexts and can be implemented simply by a jump.
Common uses
Coroutines are useful to implement the following:
*
State machines within a single subroutine, where the state is determined by the current entry/exit point of the procedure; this can result in more readable code compared to use of
goto, and may also be implemented via
mutual recursion with
tail calls.
*
Actor model
The actor model in computer science is a mathematical model of concurrent computation that treats an ''actor'' as the basic building block of concurrent computation. In response to a message it receives, an actor can: make local decisions, create ...
of concurrency, for instance in
video game
A video game or computer game is an electronic game that involves interaction with a user interface or input device (such as a joystick, game controller, controller, computer keyboard, keyboard, or motion sensing device) to generate visual fe ...
s. Each actor has its own procedures (this again logically separates the code), but they voluntarily give up control to central scheduler, which executes them sequentially (this is a form of
cooperative multitasking).
*
Generators, and these are useful for
streamsparticularly input/outputand for generic traversal of data structures.
*
Communicating sequential processes where each sub-process is a coroutine. Channel inputs/outputs and blocking operations yield coroutines and a scheduler unblocks them on completion events. Alternatively, each sub-process may be the parent of the one following it in the data pipeline (or preceding it, in which case the pattern can be expressed as nested generators).
* Reverse communication, commonly used in mathematical software, wherein a procedure such as a solver, integral evaluator, ... needs the using process to make a computation, such as evaluating an equation or integrand.
Native support
Coroutines originated as an
assembly language
In computing, assembly language (alternatively assembler language or symbolic machine code), often referred to simply as assembly and commonly abbreviated as ASM or asm, is any low-level programming language with a very strong correspondence bet ...
method, but are supported in some
high-level programming language
A high-level programming language is a programming language with strong Abstraction (computer science), abstraction from the details of the computer. In contrast to low-level programming languages, it may use natural language ''elements'', be ea ...
s.
*
Aikido
Aikido ( , , , ) is a gendai budō, modern Japanese martial art which is split into many different styles including Iwama Ryu, Iwama Shin Shin Aiki Shuren Kai, Shodokan Aikido, Yoshinkan, Renshinkai, Aikikai, and Ki Aikido. Aikido is now practic ...
*
AngelScript
*
Ballerina
*
BCPL
*
Pascal (Borland
Turbo Pascal 7.0 with uThreads module)
*
BETA
Beta (, ; uppercase , lowercase , or cursive ; or ) is the second letter of the Greek alphabet. In the system of Greek numerals, it has a value of 2. In Ancient Greek, beta represented the voiced bilabial plosive . In Modern Greek, it represe ...
*
BLISS
*
C++ (Since C++20)
*
C# (Since 2.0)
*
Chapel
A chapel (from , a diminutive of ''cappa'', meaning "little cape") is a Christianity, Christian place of prayer and worship that is usually relatively small. The term has several meanings. First, smaller spaces inside a church that have their o ...
*
ChucK
*
CLU
*
D
*
Dynamic C
*
Erlang
*
F#
*
Factor
*
GameMonkey Script
*
GDScript (Godot's scripting language)
*
Haskell
Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
*
High Level Assembly
*
Icon
An icon () is a religious work of art, most commonly a painting, in the cultures of the Eastern Orthodox, Oriental Orthodox, Catholic Church, Catholic, and Lutheranism, Lutheran churches. The most common subjects include Jesus, Mary, mother of ...
*
Io
*
JavaScript
JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior.
Web browsers have ...
(since 1.7, standardized in ECMAScript 6) ECMAScript 2017 also includes
await support.
*
Julia
*
Kotlin (since 1.1)
*
Limbo
*
Lua
*
Lucid
*
μC++
*
Modula-2
*
Nemerle
*
Perl 5 (using th
Coro module
*
PHP (wit
HipHop native since PHP 5.5)
*
Picolisp
*
Prolog
Prolog is a logic programming language that has its origins in artificial intelligence, automated theorem proving, and computational linguistics.
Prolog has its roots in first-order logic, a formal logic. Unlike many other programming language ...
*
Python (since 2.5, with improved support since 3.3 and with explicit syntax since 3.5)
*
Racket (programming language)
Racket is a General-purpose programming language, general-purpose, multi-paradigm programming language. The Racket language is a modern dialect of Lisp (programming language), Lisp and a descendant of Scheme (programming language), Scheme. It is ...
*
Raku
*
Ruby
Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
*
Sather
*
Scheme
*
Self
*
Simula
Simula is the name of two simulation programming languages, Simula I and Simula 67, developed in the 1960s at the Norwegian Computing Center in Oslo, by Ole-Johan Dahl and Kristen Nygaard. Syntactically, it is an approximate superset of AL ...
67
*
Smalltalk
Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
*
Squirrel
*
Stackless Python
*
SuperCollider
*
Tcl (since 8.6)
*
urbiscript
urbiscript is a programming language for robotics.
It features syntactic support for concurrency and event-based programming. It is a prototype-based object-oriented scripting language. It is dynamic: name resolution is performed during t ...
Since
continuation
In computer science, a continuation is an abstract representation of the control state of a computer program. A continuation implements ( reifies) the program control state, i.e. the continuation is a data structure that represents the computat ...
s can be used to implement coroutines, programming languages that support them can also quite easily support coroutines.
Implementations
, many of the most popular programming languages, including C and its derivatives, do not have built-in support for coroutines within the language or their standard libraries. This is, in large part, due to the limitations of
stack-based subroutine implementation. An exception is the C++ librar
Boost.Context part o
boost libraries which supports context swapping on ARM, MIPS, PowerPC, SPARC and x86 on POSIX, Mac OS X and Windows. Coroutines can be built upon Boost.Context.
In situations where a coroutine would be the natural implementation of a mechanism, but is not available, the typical response is to use a
closurea subroutine with state variables (
static variables, often boolean flags) to maintain an internal state between calls, and to transfer control to the correct point. Conditionals within the code result in the execution of different code paths on successive calls, based on the values of the state variables. Another typical response is to implement an explicit state machine in the form of a large and complex
switch statement
In computer programming languages, a switch statement is a type of selection control mechanism used to allow the value of a variable or expression to change the control flow of program execution via search and map.
Switch statements function ...
or via a
goto statement, particularly a
computed goto. Such implementations are considered difficult to understand and maintain, and a motivation for coroutine support.
Threads, and to a lesser extent
fibers
Fiber (spelled fibre in British English; from ) is a natural or artificial substance that is significantly longer than it is wide. Fibers are often used in the manufacture of other materials. The strongest engineering materials often inco ...
, are an alternative to coroutines in mainstream programming environments today. Threads provide facilities for managing the real-time cooperative interaction of ''simultaneously'' executing pieces of code. Threads are widely available in environments that support C (and are supported natively in many other modern languages), are familiar to many programmers, and are usually well-implemented, well-documented and well-supported. However, as they solve a large and difficult problem they include many powerful and complex facilities and have a correspondingly difficult learning curve. As such, when a coroutine is all that is needed, using a thread can be overkill.
One important difference between threads and coroutines is that threads are typically preemptively scheduled while coroutines are not. Because threads can be rescheduled at any instant and can execute concurrently, programs using threads must be careful about
locking. In contrast, because coroutines can only be rescheduled at specific points in the program and do not execute concurrently, programs using coroutines can often avoid locking entirely. This property is also cited as a benefit of
event-driven or asynchronous programming.
Since fibers are cooperatively scheduled, they provide an ideal base for implementing coroutines above.
[Implementing Coroutines for .NET by Wrapping the Unmanaged Fiber API](_blank)
, Ajai Shankar, MSDN Magazine However, system support for fibers is often lacking compared to that for threads.
C
In order to implement general-purpose coroutines, a second
call stack
In computer science, a call stack is a Stack (abstract data type), stack data structure that stores information about the active subroutines and block (programming), inline blocks of a computer program. This type of stack is also known as an exe ...
must be obtained, which is a feature not directly supported by the
C language. A reliable (albeit platform-specific) way to achieve this is to use a small amount of
inline assembly to explicitly manipulate the stack pointer during initial creation of the coroutine. This is the approach recommended by
Tom Duff in a discussion on its relative merits vs. the method used by
Protothreads.
On platforms which provide the
POSIX
The Portable Operating System Interface (POSIX; ) is a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems. POSIX defines application programming interfaces (APIs), along with comm ...
sigaltstack system call, a second call stack can be obtained by calling a springboard function from within a signal handler
to achieve the same goal in portable C, at the cost of some extra complexity. C libraries complying to
POSIX
The Portable Operating System Interface (POSIX; ) is a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems. POSIX defines application programming interfaces (APIs), along with comm ...
or the
Single Unix Specification (SUSv3) provided such routines as
getcontext, setcontext, makecontext and swapcontext, but these functions were declared obsolete in POSIX 1.2008.
Once a second call stack has been obtained with one of the methods listed above, the
setjmp and longjmp functions in the
standard C library can then be used to implement the switches between coroutines. These functions save and restore, respectively, the
stack pointer,
program counter
The program counter (PC), commonly called the instruction pointer (IP) in Intel x86 and Itanium microprocessors, and sometimes called the instruction address register (IAR), the instruction counter, or just part of the instruction sequencer, ...
, callee-saved
registers, and any other internal state as required by the
ABI, such that returning to a coroutine after having yielded restores all the state that would be restored upon returning from a function call. Minimalist implementations, which do not piggyback off the setjmp and longjmp functions, may achieve the same result via a small block of
inline assembly which swaps merely the stack pointer and program counter, and
clobbers all other registers. This can be significantly faster, as setjmp and longjmp must conservatively store all registers which may be in use according to the ABI, whereas the clobber method allows the compiler to store (by spilling to the stack) only what it knows is actually in use.
Due to the lack of direct language support, many authors have written their own libraries for coroutines which hide the above details. Russ Cox's libtask library
[http://swtch.com/libtask/ - Russ Cox's libtask coroutine library for FreeBSD, Linux, Mac OS X, and SunOS] is a good example of this genre. It uses the context functions if they are provided by the native C library; otherwise it provides its own implementations for ARM, PowerPC, Sparc, and x86. Other notable implementations include libpcl, coro, lthread, libCoroutine, libconcurrency, libcoro, ribs2, libdill., libaco, and libco.
In addition to the general approach above, several attempts have been made to approximate coroutines in C with combinations of subroutines and macros.
Simon Tatham's contribution,
based on
Duff's device, is a notable example of the genre, and is the basis for
Protothreads and similar implementations. In addition to Duff's objections,
Tatham's own comments provide a frank evaluation of the limitations of this approach: "As far as I know, this is the worst piece of C hackery ever seen in serious production code."
The main shortcomings of this approximation are that, in not maintaining a separate stack frame for each coroutine, local variables are not preserved across yields from the function, it is not possible to have multiple entries to the function, and control can only be yielded from the top-level routine.
C++
*
C++20 introduced standardized coroutines as stackless functions that can be suspended in the middle of execution and resumed at a later point. The suspended state of a coroutine is stored on the heap. Implementation of this standard is ongoing, with the G++ and MSVC compilers currently fully supporting standard coroutines in recent versions.
concurrencpp- a C++20 library which provides third-party support for C++20 coroutines, in the form of awaitable-tasks and executors that run them.
- created by Oliver Kowalke, is the official released portable coroutine library o
boostsince version 1.53. The library relies o
and supports ARM, MIPS, PowerPC, SPARC and X86 on POSIX, Mac OS X and Windows.
- also created by Oliver Kowalke, is a modernized portable coroutine library since boost version 1.59. It takes advantage of C++11 features, but removes the support for symmetric coroutines.
Mordor- In 2010,
Mozy open sourced a C++ library implementing coroutines, with an emphasis on using them to abstract
asynchronous I/O into a more familiar sequential model.
CO2- stackless coroutine based on C++
preprocessor
In computer science, a preprocessor (or precompiler) is a Computer program, program that processes its input data to produce output that is used as input in another program. The output is said to be a preprocessed form of the input data, which i ...
tricks, providing await/yield emulation.
ScummVM- The
ScummVM project implements a light-weight version of stackless coroutines based o
Simon Tatham's articletonbit::coroutine- C++11 single .h asymmetric coroutine implementation via ucontext / fiber
* Coroutines landed in
Clang
Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler ...
in May 2017, with libc++ implementation ongoing.
elleby Docker
oatpp-coroutines- stackless coroutines with scheduling designed for high-concurrency level I/O operations. Used in th
5-million WebSocket connectionsexperiment by Oat++. Part of th
Oat++web framework.
C#
C# 2.0 added semi-coroutine (
generator) functionality through the iterator pattern and
yield
keyword.
C# 5.0 includes
await syntax support. In addition:
*The '
MindTouch Dream'' REST framework provides an implementation of coroutines based on the C# 2.0 iterator pattern.
* The '
Caliburn'' () screen patterns framework for WPF uses C# 2.0 iterators to ease UI programming, particularly in asynchronous scenarios.
*The '
Power Threading Library'' () by
Jeffrey Richter implements an AsyncEnumerator that provides simplified Asynchronous Programming Model using iterator-based coroutines.
*The
Unity game engine implements coroutines.
*The '
Servelat Pieces'' project by
Yevhen Bobrov provides transparent asynchrony for Silverlight WCF services and ability to asynchronously call any synchronous method. The implementation is based on Caliburn's Coroutines iterator and C# iterator blocks.
*'
StreamThreads'' is an open-source, light-weight C# co-routine library based on iterator extension methods. It supports error handling and return values.
Clojure
Cloroutineis a third-party library providing support for stackless coroutines in
Clojure
Clojure (, like ''closure'') is a dynamic programming language, dynamic and functional programming, functional dialect (computing), dialect of the programming language Lisp (programming language), Lisp on the Java (software platform), Java platfo ...
. It's implemented as a macro, statically splitting an arbitrary code block on arbitrary var calls and emitting the coroutine as a stateful function.
D
D implements coroutines as its standard library clas
FiberA ''generator'' makes it trivial to expose a fiber function as an ''input range'', making any fiber compatible with existing range algorithms.
Go
Go has a built-in concept of "
goroutines", which are lightweight, independent processes managed by the Go runtime. A new goroutine can be started using the "go" keyword. Each goroutine has a variable-size stack which can be expanded as needed. Goroutines generally communicate using Go's built-in channels. However, goroutines are not coroutines (for instance, local data does not persist between successive calls).
Java
There are several implementations for coroutines in
Java
Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
. Despite the constraints imposed by Java's abstractions, the JVM does not preclude the possibility.
There are four general methods used, but two break bytecode portability among standards-compliant JVMs.
* Modified JVMs. It is possible to build a patched JVM to support coroutines more natively. Th
Da Vinci JVMhas had patches created.
* Modified bytecode. Coroutine functionality is possible by rewriting regular Java bytecode, either on the fly or at compile time. Toolkits includ
JavaflowJava Coroutines an
Coroutines
* Platform-specific JNI mechanisms. These use JNI methods implemented in the OS or C libraries to provide the functionality to the JVM.
* Thread abstractions. Coroutine libraries which are implemented using threads may be heavyweight, though performance will vary based on the JVM's thread implementation.
JavaScript
Since
ECMAScript 2015, JavaScript has support for
generators, which are a special case of coroutines.
Kotlin
Kotlin implements coroutines as part of a first-party library.
Lua
Lua has supported first-class stackful asymmetric coroutines since version 5.0 (2003), in the standard library ''coroutine''.
Modula-2
Modula-2 as defined by
Wirth implements coroutines as part of the standard SYSTEM library.
The procedure NEWPROCESS() fills in a context given a code block and space for a stack as parameters, and the procedure TRANSFER() transfers control to a coroutine given the coroutine's context as its parameter.
Mono
The
Mono Common Language Runtime has support for continuations,
[http://www.mono-project.com/Continuations Mono Continuations] from which coroutines can be built.
.NET Framework
During the development of the
.NET Framework 2.0, Microsoft extended the design of the
Common Language Runtime (CLR) hosting APIs to handle fiber-based scheduling with an eye towards its use in fiber-mode for SQL server.
[http://blogs.msdn.com/cbrumme/archive/2004/02/21/77595.aspx , Chris Brumme]
cbrumme's WebLog
Before release, support for the task switching hook ICLRTask::SwitchOut was removed due to time constraints. Consequently, the use of the fiber API to switch tasks is currently not a viable option in the .NET Framework.
OCaml
OCaml supports coroutines through its
Thread
module. These coroutines provide concurrency without parallelism, and are scheduled preemptively on a single operating system thread. Since OCaml 5.0,
green threads are also available; provided by different modules.
Perl
Coro
Coroutines are natively implemented in all
Raku backends.
PHP
Fibersnative since PHP 8.1
AmphpOpen SwooleCoroutineimplemented in a way that resembles
Python functions, and some
Go, man
examplesshowing there code converted with same number of lines and behavior.
Python
*
Python 2.5 implements better support for coroutine-like functionality, based on extended generators
PEP 342
*
Python 3.3 improves this ability, by supporting delegating to a subgenerator
PEP 380
*
Python 3.4 introduces a comprehensive asynchronous I/O framework as standardized i
PEP 3156 which includes coroutines that leverage subgenerator delegation
*
Python 3.5 introduces explicit support for coroutines with async/
await syntax
PEP 0492.
*Since
Python 3.7, async/await have become reserved keywords.
EventletGreenletgeventstackless python
Racket
Racket provides native continuations, with a trivial implementation of coroutines provided in the official package catalog
Implementation by S. De Gabrielle
Ruby
*
Ruby
Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
1.9 supports coroutines natively which are implemented a
fibers which are semi-coroutines.
An implementation by Marc De Scheemaecker*
Ruby
Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
2.5 and higher supports coroutines natively which are implemented a
fibersAn implementation by Thomas W Branson
Scheme
Since
Scheme provides full support for continuations, implementing coroutines is nearly trivial, requiring only that a queue of continuations be maintained.
Smalltalk
Since, in most
Smalltalk
Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
environments, the execution stack is a first-class citizen, coroutines can be implemented without additional library or VM support.
Tool Command Language (Tcl)
Since version 8.6, the Tool Command Language supports coroutines in the core language.
Vala
Vala implements native support for coroutines. They are designed to be used with a Gtk Main Loop, but can be used alone if care is taken to ensure that the end callback will never have to be called before doing, at least, one yield.
Assembly languages
Machine-dependent
assembly language
In computing, assembly language (alternatively assembler language or symbolic machine code), often referred to simply as assembly and commonly abbreviated as ASM or asm, is any low-level programming language with a very strong correspondence bet ...
s often provide direct methods for coroutine execution. For example, in
MACRO-11, the assembly language of the
PDP-11 family of minicomputers, the "classic" coroutine switch is effected by the instruction "JSR PC,@(SP)+", which jumps to the address popped from the stack and pushes the current (''i.e'' that of the next) instruction address onto the stack. On
VAXen (in
VAX MACRO) the comparable instruction is "JSB @(SP)+". Even on a
Motorola 6809 there is the instruction "JSR
S++; note the "++", as 2 bytes (of address) are popped from the stack. This instruction is much used in the (standard) 'monitor'
Assist 09.
See also
*
Async/await
*
Pipeline
A pipeline is a system of Pipe (fluid conveyance), pipes for long-distance transportation of a liquid or gas, typically to a market area for consumption. The latest data from 2014 gives a total of slightly less than of pipeline in 120 countries ...
, a kind of coroutine used for communicating between programs
*
Protothreads, a stackless lightweight thread implementation using a coroutine like mechanism
References
Further reading
*
External links
*
Simon Tatham's C oriente
comprehensive introduction to coroutinesSoftpanorama coroutine page{sndcontains extensive assembler coroutines links
Concurrent computing
Subroutines