«Сопрограмма» в общепринятом смысле - это, по сути, функция, которую - однажды начав - можно представить как выполняющуюся рядом с вызывающим абонентом.То есть, когда сопрограмма «уступает» (полу особый вид возврата), это не обязательно делается - и «повторный вызов» ее заставит сопрограмму подхватить то место, где она остановилась, со всем ее состоянием без изменений, а не начиная с самого начала.Таким образом, вызовы можно рассматривать как своего рода передачу сообщений между двумя функциями.
Немногие языки полностью и естественным образом делают это.(Для стековых языков, как правило, трудно с этим работать, при отсутствии некоторых функциональных возможностей, таких как «волокна» Windows.) Очевидно, Ruby это делает, а Python использует его ограниченную версию.Я считаю, что они называют это «генератором», и он в основном используется как итеративная коллекция (чей итератор генерирует свой следующий «элемент» на лету).C # также может делать это частично (они называют это «итератором»), но компилятор фактически превращает функцию в класс, который реализует своего рода конечный автомат.