All Topics  
Coroutine

 

   Email Print
   Bookmark   Link






 

Coroutine



 
 
In computer science
Computer science

Computer science is the study of the theoretical foundations of information and computation, and of practical techniques for their implementation and application in computer systems....
, coroutines are program components that generalize subroutine
Subroutine

In computer science, a subroutine or subprogram is a portion of computer code within a larger computer program, which performs a specific task and is relatively independent of the remaining code....
s to allow multiple entry points for suspending and resuming of execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterator
Iterator

In computer science, an iterator is an object that allows a programmer to traverse through all the elements of a Collection , regardless of its specific implementation....
s, infinite lists
Lazy evaluation

In computer programming, lazy evaluation is the technique of delaying a computation until such time as the result of the computation is known to be needed....
 and pipes
Pipeline (software)

In software engineering, a pipeline consists of a chain of processing elements , arranged so that the output of each element is the input of the next....
.

The term "coroutine" was originated by Melvin Conway
Melvin Conway

Melvin Conway was an early computer scientist, computer programmer, and Hacker who coined what's now known as Conway's Law: "Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations."...
 in his seminal 1963 paper.

Comparison with subroutines
Coroutines are more generic than subroutines.






Discussion
Ask a question about 'Coroutine'
Start a new discussion about 'Coroutine'
Answer questions from other users
Full Discussion Forum



Encyclopedia


In computer science
Computer science

Computer science is the study of the theoretical foundations of information and computation, and of practical techniques for their implementation and application in computer systems....
, coroutines are program components that generalize subroutine
Subroutine

In computer science, a subroutine or subprogram is a portion of computer code within a larger computer program, which performs a specific task and is relatively independent of the remaining code....
s to allow multiple entry points for suspending and resuming of execution at certain locations. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterator
Iterator

In computer science, an iterator is an object that allows a programmer to traverse through all the elements of a Collection , regardless of its specific implementation....
s, infinite lists
Lazy evaluation

In computer programming, lazy evaluation is the technique of delaying a computation until such time as the result of the computation is known to be needed....
 and pipes
Pipeline (software)

In software engineering, a pipeline consists of a chain of processing elements , arranged so that the output of each element is the input of the next....
.

The term "coroutine" was originated by Melvin Conway
Melvin Conway

Melvin Conway was an early computer scientist, computer programmer, and Hacker who coined what's now known as Conway's Law: "Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations."...
 in his seminal 1963 paper.

Comparison with subroutines


Coroutines are more generic than subroutines. The lifespan of subroutines is dictated by last in, first out (the last subroutine called is the first to return); in contrast, the lifespan of coroutines is dictated entirely by their use and need.

The start of a subroutine is the only point of entry. Subroutines can return only once; in contrast, coroutines can return (yield) several times. The start of a coroutine is the first point of entry and subsequent points of entry are following yield commands. Practically, yielding returns the result to the calling coroutine and gives it back control, like a usual subroutine. However, the next time the coroutine is called, the execution does not start at the beginning of the coroutine but just after the yield call.

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

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 inner coroutine loop.

Although this example is often used to introduce multithreading, it is not necessary to have two threads to achieve this: the yield statement can be implemented by a branch directly from one routine into the other.

Detailed comparison

Since coroutines can have more points of entry and exit than subroutines, it is possible to implement any subroutine as a coroutine. "Subroutines are special cases of ... coroutines." —Donald Knuth
Donald Knuth

Donald Ervin Knuth is a renowned computer science and Emeritus of the Art of Computer Programming at Stanford University.Author of the seminal multi-volume work The Art of Computer Programming , Knuth has been called the "father" of the run-time analysis, contributing to the development of, and systematizing formal mathematical techn...


Each time a subroutine is called (invoked), execution starts at the beginning of the invoked subroutine. Likewise, the first time a coroutine is invoked, execution starts at the beginning of the coroutine; however, each subsequent time a coroutine is invoked, execution resumes following the place where the coroutine last returned (yielded).

A subroutine returns only once. In contrast, a coroutine can return multiple times, making it possible to return additional values upon subsequent calls to the coroutine. Coroutines in which subsequent calls yield additional results are often known as generators
Generator (computer science)

In computer science, a generator is a special subroutine that can be used to control the iteration behaviour of a control flow#Loops. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values....
.

Subroutines only require a single stack
Stack (data structure)

In computer science, a stack is an abstract data type and data structure based on the principle of LIFO . Stacks are used extensively at every level of a modern computer system....
 that can be preallocated at the beginning of program execution. In contrast, coroutines, able to call on other coroutines as peers, are best implemented using continuation
Continuation

In computing and programming, a continuation is an abstract representation of Control flow, or the "rest of computation" or "rest of code to be executed"....
s. Continuations may require allocation of additional stacks and therefore are more commonly implemented in garbage-collected high-level languages. Coroutine creation can be done cheaply by preallocating stacks or caching previously allocated stacks.

Coroutines and generators

Generators
Generator (computer science)

In computer science, a generator is a special subroutine that can be used to control the iteration behaviour of a control flow#Loops. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values....
 are also a generalisation of subroutines, but with at first sight less expressive power than coroutines; since generators are primarily used to simplify the writing of iterator
Iterator

In computer science, an iterator is an object that allows a programmer to traverse through all the elements of a Collection , regardless of its specific implementation....
s, 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 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 consume

generator consume loop while q is not empty remove some items from q use the items yield produce

subroutine dispatcher var d := new dictionary<generator ? iterator> d[produce] := start produce d[consume] := start consume var current := produce loop current := next d[current]

A number of implementations of coroutines for languages with generator support but no native coroutines (e.g. Python prior to 2.5) use this or a similar model.

Common uses of coroutines

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.
  • Actor model
    Actor model

    In computer science, the Actor model is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message receiv...
     of concurrency, for instance in computer games. 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
    Generator (computer science)

    In computer science, a generator is a special subroutine that can be used to control the iteration behaviour of a control flow#Loops. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values....
    , and these are useful for input/output and for generic traversal of data structures.


Programming languages supporting coroutines


  • Aikido
    Aikido (programming language)

    Aikido is a relatively new programming language that can be used for rapid scripting, prototyping andgeneral programming tasks. It was developed in Sun Microsystems Laboratories by David Allison...
  • BETA
    BETA

    BETA is a pure object-oriented language originating within the "Scandinavian School" in object-orientation where the first object-oriented language Simula programming language was developed....
  • ChucK
    ChucK

    ChucK is a concurrent, strongly-timed audio programming language for real-time synthesis, composition, and performance, which runs on Mac OS X, Linux, and Microsoft Windows....
  • Dynamic C
  • Factor
  • Haskell
    Haskell (programming language)

    Haskell is a standardized, purely functional programming language with non-strict programming language, named after logician Haskell Curry. The goals of the language are described as:...
  • High Level Assembly
    High Level Assembly

    High Level Assembler is an assembly language developed by Randall Hyde which can use high-level language constructs to aid x86 assembly language programmer beginners and advanced assembly developers alike....
  • JavaScript
    JavaScript

    JavaScript is a scripting language widely used for client-side web development. It was the originating Programming language dialect of the ECMAScript standard....
     (since 1.7)
  • Icon
  • Io
    Io (programming language)

    Io is a pure Object-oriented programming Computer programming Programming language inspired by Smalltalk, Self , Lua , Lisp , Act1, and NewtonScript....
  • Limbo
  • Lua
  • Lucid
  • µC++
  • MiniD
    MiniD

    The MiniD programming language is a small, lightweight, extension language in the vein of Lua or Squirrel , but designed to be used mainly with the D ....
  • Modula-2
    Modula-2

    Modula-2 is a computer programming language invented by Niklaus Wirth at ETH, around 1978, as a successor to his intermediate language Modula. Modula-2 was implemented in 1980 for the Lilith computer, which was commercialized in 1982 by startup company DISER as MC1 and MC2....
  • Perl
    Perl

    In computer programming, Perl is a high-level programming language, List of programming languages by category, Interpreter , dynamic programming language....
     (Perl 5 with Coro, Perl 6 native)
  • Python
    Python (programming language)

    Python is a general-purpose high-level programming language. Its design philosophy emphasizes code readability. Python's core syntax and semantics are Minimalism , while the standard library is large and comprehensive....
     (since 2.5)
  • Ruby (since 1.9, using Fibers)
    Ruby (programming language)

    Ruby is a dynamic programming language, reflection , general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features....
  • Scheme
  • Self
  • Simula-67
    Simula

    Simula is a name for two 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....
  • Squirrel
  • Stackless Python
    Stackless Python

    Stackless Python, or Stackless, is a Python interpreter, so named because it avoids depending on the C call stack for its own stack. The most prominent feature of Stackless is Microthread, which avoid much of the overhead associated with usual operating system Thread s....
  • SuperCollider
    Supercollider

    A Supercollider is a high energy particle accelerator. The term may refer to:* Superconducting Super Collider, planned 80 km project in Texas, canceled in 1993...


Since continuation
Continuation

In computing and programming, a continuation is an abstract representation of Control flow, or the "rest of computation" or "rest of code to be executed"....
s can be used to implement coroutines, programming languages that support them can also quite easily support coroutines.

Coroutine alternatives and implementations


Coroutines originated as an assembly-language
Assembly language

An assembly language is a low-level language for programming computers. It implements a symbolic representation of the numeric machine codes and other constants needed to program a particular CPU architecture....
 technique, but are supported in some high-level languages, Simula
Simula

Simula is a name for two 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....
 and Modula-2
Modula-2

Modula-2 is a computer programming language invented by Niklaus Wirth at ETH, around 1978, as a successor to his intermediate language Modula. Modula-2 was implemented in 1980 for the Lilith computer, which was commercialized in 1982 by startup company DISER as MC1 and MC2....
 being two early examples.

, many of the most popular programming languages, including C and its derivatives, do not have direct support for coroutines within the language or their standard libraries. (This is, in large part, due to the limitations of stack-based
Call stack

In computer science, a call stack is a dynamic Stack data structure that stores information about the active subroutines of a computer program....
 subroutine implementation).

In situations where a coroutine would be the natural implementation of a mechanism, but is not available, the typical response is to create a subroutine that uses an ad-hoc assemblage of boolean flags and other state variables to maintain an internal state between calls. 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. Such implementations are difficult to understand and maintain.

Threads
Thread (computer science)

In computer science, a thread of execution is a Fork of a computer program into two or more Concurrency running task s. The implementation of threads and process es differs from one operating system to another, but in most cases, a thread is contained inside a process....
 (and to a lesser extent fibers
Fiber (computer science)

In computer science, a fiber is a particularly lightweight thread of execution.Like threads, fibers share address space; where a distinction exists, it is that fibers use Computer multitasking#Cooperative multitasking/time-sharing while threads use pre-emptive multitasking....
) are an alternative to coroutines in mainstream programming environments today. Threads provide facilities for managing the realtime 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
Lock (computer science)

In computer science, a lock is a Synchronization mechanism for enforcing limits on access to a resource in an environment where there are many thread ....
. 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
Event-driven programming

In computer programming, event-driven programming or event-based programming is a programming paradigm in which the Program flow is determined by event s — i.e., sensor outputs or user actions or Message passing from other programs or Thread_....
 or asynchronous programming.)

Since fibers are cooperatively scheduled, they provide an ideal base for implementing coroutines above. However, system support for fibers is often lacking compared to that for threads.

Implementation in the .NET Framework
.NET Framework

The Microsoft .NET Framework is a software framework that is available with several Microsoft Windows operating systems. It includes a large Library of coded solutions to prevent common programming problems and a virtual machine that manages the execution of programs written specifically for the Software framework....
 as fibers


During the development of the .NET Framework 2.0, Microsoft extended the design of the CLR
Common Language Runtime

The Common Language Runtime is a core component of Microsoft .NET Framework initiative. It is Microsoft's implementation of the Common Language Infrastructure standard, which defines an execution environment for program code....
 hosting APIs to handle fiber-based scheduling with an eye towards its used in fiber-mode for SQL server. Prior to release, support for the task switching hook ICLRTaskSwitchOut 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.

Implementations for C
C (programming language)

C is a general-purpose computer programming language originally developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories to implement the Unix operating system....

Several attempts have been made, with varying degrees of success, to implement coroutines in C with combinations of subroutines and macros. Simon Tatham
Simon Tatham

Simon Tatham is an English programmer known primarily for creating and maintaining PuTTY, a free software implementation of Telnet and Secure Shell clients for Win32 and Unix platforms, along with an xterm terminal emulator....
's contribution is a good example of the genre, and his own comments provide a good evaluation of the limitations of this approach. The use of such a device truly can improve the writability, readability and maintainability of a piece of code, but is likely to prove controversial. In Tatham's words: "Of course, this trick violates every coding standard in the book... [but] any coding standard which insists on syntactic clarity at the expense of algorithmic clarity should be rewritten. If your employer fires you for using this trick, tell them that repeatedly as the security staff drag you out of the building."

A more reliable approach to implementing coroutines in C is to give up on absolute portability and write processor-family-specific implementations, in assembly, of functions to save and restore a coroutine context. The standard C library includes functions named setjmp and longjmp which can be used to implement a form of coroutine. Unfortunately, as Harbison and Steele note, "the setjmp and longjmp functions are notoriously difficult to implement, and the programmer would do well to make minimal assumptions about them." What this means is if Harbison and Steele's many cautions and caveats are not carefully heeded, uses of setjmp and longjmp that appear to work in one environment may not work in another. Worse yet, faulty implementations of these routines are not rare. Indeed, setjmp/longjmp, because it only countenances a single stack, cannot be used to implement natural coroutines, as variables located on the stack will be overwritten as another coroutine uses the same stack space.

Thus for stack-based coroutines in C, functions are needed to create and jump between alternate stacks. A third function, which can usually be written in machine-specific C, is needed to create the context for a new coroutine. C libraries complying to POSIX
POSIX

POSIX or "Portable Operating System Interface" is the collective name of a family of related standardizations specified by the Institute of Electrical and Electronics Engineers to define the application programming interface , along with shell and utilities interfaces for software compatible with variants of the Unix operating system, altho...
 or the Single Unix Specification
Single UNIX Specification

The Single UNIX Specification is the collective name of a family of standards for computer operating systems to qualify for the name "Unix". The SUS is developed and maintained by the Austin Group, based on earlier work by the IEEE and The Open Group....
 provide such routines as getcontext, setcontext, makecontext and swapcontext
Setcontext

setcontext is one of a family of C library Subroutines used for context control. The setcontext family allows the implementation in C of advanced control flow design patterns such as iterators, fiber , and coroutines....
. The setcontext family of functions is thus considerably more powerful than setjmp/longjmp, but conforming implementations are as rare if not rarer. The main shortcoming of this approach is that the coroutine's stack is a fixed size and cannot be grown during execution. Thus, programs tend to allocate much more stack than they actually need in order to avoid the potential for stack overflow.

Due to the limitations of standard libraries, some authors have written their own libraries for coroutines. Russ Cox's libtask library 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, libCoroutine and libcoro.

Implementations for Python
Python (programming language)

Python is a general-purpose high-level programming language. Its design philosophy emphasizes code readability. Python's core syntax and semantics are Minimalism , while the standard library is large and comprehensive....

  • - better support for coroutine-like functionality, based on extended generators (implemented in Python 2.5)


Implementations for Ruby

  • (with commentary in Japanese language)


Implementations for Perl
Perl

In computer programming, Perl is a high-level programming language, List of programming languages by category, Interpreter , dynamic programming language....

Coroutines will also be a part of Perl 6
Perl 6

Perl 6 is a planned major revision to the Perl programming language. It is a language specification which introduces elements of many modern and historical languages....
.

Implementations for Smalltalk
Smalltalk

Smalltalk is an Object-oriented programming, Type system, reflection computer programming programming language. Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human?computer symbiosis." It was designed and created in part for educational use, more so for constructionist learning, at PARC by Al...

Since in most Smalltalk environments the execution stack is a first-class citizen, Coroutine can be implemented without additional library or VM support.

Implementations for Delphi

  • Coroutine implementation by Bart van der Werf
  • by Sergey Antonov


Implementations in assembly languages

Machine-dependent assembly languages often provide direct methods for coroutine execution. For example, in MACRO-11
MACRO-11

MACRO-11 is an assembly language with Macro facilities for PDP-11 minicomputers from Digital Equipment Corporation . It is the successor to PAL-11 , an earlier version of the PDP-11 assembly language without Macro facilities....
, the assembly language of the PDP_11 family
PDP-11

The PDP-11 was a series of 16-bit minicomputers sold by Digital Equipment Corporation from 1970 into the 1990s. Though not explicitly conceived as successor to DEC's PDP-8 computer in the Programmed Data Processor series of computers , the PDP-11 replaced the PDP-8 in many Real-time computing....
 of minicomputers, the “classic” coroutine switch is effected by the instruction "JSR PC,@(SP)+" (which assembles as octal "004736") 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
VAX

VAX was an instruction set architecture developed by Digital Equipment Corporation in the mid-1970s. A 32-bit complex instruction set computer ISA, it was designed to extend or replace DEC's various Programmed Data Processor ISAs....
 (in Macro-32
VAX Macro

VAX Macro is the assembly language implementing the instruction set for the line of CPUs designed to run the OpenVMS operating system created by Digital Equipment Corporation in 1977....
) the comparable instruction is "JSB @(SP)+" (which assembles as hex "9E 16" as the assembler shows it (with in effect bytes reversed). Even on a Motorola 6809
Motorola 6809

The Motorola 6809 is an 8-bit microprocessor central processing unit from Motorola, introduced circa 1977-78. It was a major advance over both its predecessor, the Motorola 6800, and the related, MOS Technology 6502....
 there is the instruction "JSR [,S++]", which assembles as (hex) "AD F1"; note the "++", as 2 bytes (of address) are popped from the stack. This instruction is much used in the (standard) 'monitor' Assist_09.

Simply calling back the routine whose address is on the top of the stack, does not, of course, exhaust the possibilities in assembly language(s)!

See also

  • Cooperative multitasking
  • Iterator
    Iterator

    In computer science, an iterator is an object that allows a programmer to traverse through all the elements of a Collection , regardless of its specific implementation....
  • Fibers
    Fiber (computer science)

    In computer science, a fiber is a particularly lightweight thread of execution.Like threads, fibers share address space; where a distinction exists, it is that fibers use Computer multitasking#Cooperative multitasking/time-sharing while threads use pre-emptive multitasking....
  • Generator (computer science)
    Generator (computer science)

    In computer science, a generator is a special subroutine that can be used to control the iteration behaviour of a control flow#Loops. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values....
  • Lazy evaluation
    Lazy evaluation

    In computer programming, lazy evaluation is the technique of delaying a computation until such time as the result of the computation is known to be needed....
  • Pipe (computing)
  • Protothreads
    Protothreads

    In computer science, a protothread is a low-overhead mechanism for concurrent programming.Protothreads function as Call stack, lightweight Thread providing a blocking context cheaply using minimal memory per protothread ....
  • Subroutine
    Subroutine

    In computer science, a subroutine or subprogram is a portion of computer code within a larger computer program, which performs a specific task and is relatively independent of the remaining code....


External links


  • Simon Tatham
    Simon Tatham

    Simon Tatham is an English programmer known primarily for creating and maintaining PuTTY, a free software implementation of Telnet and Secure Shell clients for Win32 and Unix platforms, along with an xterm terminal emulator....
    's C oriented


  • Dan Sugalski's less formal , including a discussion of how to handle resumption with different parameters.


  • Contains extensive assembler coroutines links.