Минусы первого класса продолжений

Какова некоторая критика, направленная против разоблачения продолжений как объектов первого класса?

Я чувствую, что хорошо иметь продолжение первого класса. Это позволяет полностью контролировать поток выполнения инструкций. Опытные программисты могут разработать интуитивно понятные решения для определенного рода проблем. Например, продолжения используются для управления состоянием на веб-серверах. Языковая реализация может предоставить полезные абстракции поверх продолжений. Например, зеленые нитки.

Несмотря на все это, есть ли веские аргументы против продолжения первого класса?

7 ответов

Решение

Во-первых, это больше, чем просто вызов /cc, когда дело доходит до продолжения. Я предлагаю начать с статьи Марка Филиса: лучший API для продолжения первого класса

Далее я предлагаю прочитать об управляющих операторах смещения и сброса, которые представляют собой другой способ представления контунаций.

Реальность такова, что многие полезные ситуации, в которых вы можете использовать продолжения, уже покрыты специальными языковыми конструкциями: throw/catch, return, C#/Python yield. Таким образом, у языковых разработчиков на самом деле нет такого большого стимула предоставлять их в обобщенной форме, которую можно использовать для решений по принципу "сами по себе".

В некоторых языках обобщенные продолжения довольно сложно реализовать эффективно. Основанные на стеке языки (т.е. большинство языков) в основном должны копировать весь стек каждый раз, когда вы создаете продолжение.

Эти языки могут реализовывать определенные функции, подобные продолжению, те, которые не нарушают базовую модель на основе стека, намного эффективнее, чем общий случай, но реализация обобщенных продолжений немного сложнее и не стоит того.

Функциональные языки с большей вероятностью реализуют продолжения по нескольким причинам:

  1. Они часто реализуются в стиле передачи продолжения, что означает, что "стек вызовов", вероятно, является связанным списком, размещенным в куче. Это упрощает передачу указателя на стек в качестве продолжения, поскольку вам не нужно перезаписывать контекст стека, когда вы извлекаете текущий кадр и вставляете новый. (Я никогда не использовал CPS, но это мое понимание).
  2. Они предпочитают неизменные привязки данных, которые делают ваше старое продолжение намного более полезным, потому что вы не изменили содержимое переменных, на которые указывал стек при создании.

По этим причинам продолжения, скорее всего, останутся в основном только в области функциональных языков.

Существенным возражением является стоимость внедрения. Если среда выполнения использует стек, то для продолжения первого класса в какой-то момент требуется копия стека. Стоимость копирования может контролироваться (см. Представление управления в присутствии первоклассных продолжений для хорошей стратегии), но это также означает, что изменяемые переменные не могут быть размещены в стеке. Это не проблема для функциональных или в основном функциональных (например, Scheme) языков, но это добавляет значительную нагрузку для ОО-языков.

  1. Большинство программистов не понимают их. Если у вас есть код, который их использует, труднее найти замену программистам, которые смогут с ним работать.
  2. Продолжения трудно реализовать на некоторых платформах. Например, JRuby не поддерживает продолжения.

Первоклассные продолжения подрывают способность рассуждать о коде, особенно в языках, которые позволяют императивно присваивать продолжения переменным, потому что внутренности замыканий можно снова оживить волосатыми способами.

Ср Жалоба Кента Питмана на продолжение, на хитрый способ, которым раскрутка-защита взаимодействует с call/cc

В ruby ​​1.8 реализация была крайне медленной. лучше в 1.9, и, конечно, в большинстве схем они были встроены и работали хорошо с самого начала.

Call/cc - это "goto" для расширенного функционального программирования (в качестве примера здесь).

Другие вопросы по тегам