Эм, сейчас я тебе объясню, в чём фишка корутин. Возможно, ты не поймешь сразу, но ты можешь переспрашивать. Корутины - это из императивного программирования. Это способ взять кусок императивного кода и сделать его асинхронным и не сойти ума. Точно также, как ФП удобно для паралельного программирования, императивное удобно для асинхронного.
Я не хочу быть тем занудой, но чуть-чуть придётся.
Со всем уважением, но мало того, что у тебя абсолютно неверное представление о проблеме, так ты ещё и распространяешь его среди молодых умов, которые могут воспринять это всерьёз.
Во-первых, «корутины - из императивного программирования» это совсем ошибочное заявление.
Корутины это легковесные потоки, НИКАКОГО отношения к парадигме программирования они не имеют.
Они дают возможность приостановить выполнение кода в определенной точке, сохранить состояние стека вызовов, выполнить другой код и вернуться к сохраненному состоянию. Тем самым реализуя многопоточность (даже на одном ядре). Более подробно смотри в вики, у кнута и ещё погугли scheme continuations.
Так же ни в коем случае не нужно использовать слова «императивный» и «асинхронный» как антонимы, это две абсолютно разных характеристики, как мокрый и красный например.
ФП действительно удобно для параллельного программирования, но лишь когда ты используешь чистые функции и не делаешь shared mutable state. Таким же удобным станет джава, если не шарить данные между потоками.
«Императивное удобно для асинхронного» - писал выше. Сравнение пальца с дверной ручкой.
Как только вы разберетесь в понятиях императивный, декларативный, параллельный, асинхронный, фп, корутина, continuation, тогда всё станет намного понятней)