Реальность такова, что многие полезные ситуации, в которых вы можете использовать продолжения, уже покрыты специальными языковыми конструкциями: throw / catch, return, C # / Python yield. Таким образом, у языковых разработчиков на самом деле нет такого большого стимула предоставлять их в обобщенной форме, которую можно использовать для решений по принципу «накатить».
В некоторых языках обобщенные продолжения довольно сложно реализовать эффективно. Языки на основе стека (т.е. большинство языков) в основном должны копировать весь стек каждый раз, когда вы создаете продолжение.
Эти языки могут реализовывать определенные функции, подобные продолжению, те, которые не нарушают базовую модель на основе стека, гораздо эффективнее, чем общий случай, но реализация обобщенных продолжений немного сложнее и не стоит.
Функциональные языки с большей вероятностью реализуют продолжения по нескольким причинам:
- Они часто реализуются в стиле передачи продолжения, что означает, что «стек вызовов», вероятно, является связанным списком, размещенным в куче. Это упрощает передачу указателя на стек в качестве продолжения, поскольку вам не нужно перезаписывать контекст стека, когда вы извлекаете текущий кадр и вставляете новый. (Я никогда не использовал CPS, но это мое понимание).
- Они предпочитают неизменные привязки данных, которые делают ваше старое продолжение намного более полезным, потому что вы не изменили содержимое переменных, на которые указывал стек при создании.
По этим причинам продолжения, скорее всего, останутся в основном только в области функциональных языков.