| # Coroutines | |
| In Wuffs, coroutines are functions that can suspend their execution in the | |
| middle of the function body, yielding (returning) a | |
| [status](/doc/note/statuses.md) that is a suspension. Calling that function | |
| again will resume that function where it left off. Calling any other coroutine | |
| function on the same receiver, whilst it is suspended, will result in an error. | |
| Unlike coroutines in other programming languages, Wuffs coroutines cannot | |
| return other values in addition to that status, and statuses don't carry | |
| additional fields. Wuffs coroutines cannot be used as generators directly, | |
| although they can produce to and consume from buffers as side effects. The | |
| built-in I/O types (`base.io_reader` and `base.io_writer`) have coroutine | |
| methods that are exceptions to this "no additional return value" rule, and are | |
| special-cased by the Wuffs compiler. | |
| Another difference with other programming languages is that Wuffs coroutines' | |
| arguments can change across a suspension and resumption. The mechanism for | |
| resuming a coroutine, for C code that calls into Wuffs-transpiled-to-C, is to | |
| simply call the C function again, with the same `self` receiver (the first | |
| argument), but with potentially different other arguments. | |
| As of Wuffs version 0.2 (December 2019), the language and standard library use | |
| only two suspension status values, both [I/O](/doc/note/io-input-output.md) | |
| related: `"$short read"` and `"$short write"` are used when a source buffer is | |
| empty (and needs re-filling) or a destination buffer is full (and needs | |
| flushing). These I/O related suspensions, together with the I/O buffer | |
| arguments' contents and read/write indexes changing, are how [compression | |
| decoders](/doc/std/compression-decoders.md) are able to decompress from | |
| arbitrarily long inputs to arbitrarily long outputs with fixed sized buffers. | |
| Wuffs coroutines are stackful, in that they can call other coroutines, although | |
| not recursively. When suspended, coroutine state is stored in the receiver | |
| struct. Wuffs has no free standing functions (and therefore no free standing | |
| coroutines), only methods (functions with a receiver). | |
| Wuffs code (as opposed to a C program calling into a Wuffs library) can only | |
| call coroutines from within a method that is also a coroutine. If the callee | |
| suspends, then the caller will also suspend, by default, unless the callee's | |
| status result is assigned via the `=?` operator. | |
| Syntactically, coroutines are marked by a question mark, `?`, at their | |
| definition and at call sites, implying that their return type is a | |
| `base.status`. The `yield` keyword is also always immediately followed by `?`, | |
| so that grepping a function's body for the literal question mark will find all | |
| of the potential suspension points. | |
| As for [facts](/doc/note/facts.md), crossing a potential suspension point drops | |
| any facts involving `this` or `args`. Facts only involving local variables are | |
| preserved. |