symmetric v.s. asymmetric coroutine
2023年1月26日关于coroutine的词汇非常混乱,就连coroutine本身也没有一个唯一的公认定义。the fundamental characteristics of a coroutine (Marlin要求):[1]
- 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
we can identify three main issues that distinguish different kinds of coroutine facilities:
- the control-transfer mechanism, which can provide symmetric or asymmetric coroutines;
- 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 implemented as a stackful construct, that is, whether it is able to suspend its execution from within nested calls.
本文研究第一个选项——symmetric v.s. asymmetric coroutine。《stackful v.s. stackless coroutine》则探讨第三个选项。
大部分语言提供的coroutine都会符合Marlin要求,但对上述三个选项则自由选取。《Revisiting Coroutines》把支持first-class和stackful的coroutine叫做full coroutine。因此full asymmetric coroutine就是asymmetric, first-class, stackful的coroutine。
asymmetric coroutines 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.
Lua offers asymmetric coroutines.
Some people call asymmetric coroutine semi-coroutines. 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. Generators in Python are also stackless coroutine.
https://www.lua.org/pil/9.1.html
正如《stackful v.s. stackless coroutine》介绍的,stackful coroutine是调用栈里自此以后的所有部分。任何一帧yield,会直接返回到创建该stackful coroutine的那一帧,也只能返回到那一帧。If A calls coroutine B, B calls coroutines C, C cannot yield directly to A.[2]有这种限制的,叫做asymmetric coroutine。
Symmetric coroutines相当于有一个goto命令,但它不是在statements之间跳,而是在coroutines之间跳。用得不好也是一个灾难。
In terms of expressive power, symmetric coroutines and asymmetric coroutines are expressive to the same extent.
参考资料
- ANA LUCIA DE MOURA ; ROBERTO IERUSALIMSCHY. Revisiting Coroutines. . 2009-02, (): [].↑
- . Symmetric coroutines. . 2006 [2023-01-26].↑