Почему сопрограммы имеют будущее? - PullRequest
0 голосов
/ 09 сентября 2018

Получив сопрограммы, вы можете создавать конвейеры (haskell: каналы, каналы; python: генераторы) или кооперативные циклы событий (python: curio). Если у вас есть будущее, кажется, вы можете сделать то же самое; трубопроводы (ржавчина: фьючерс-rs) и петли событий (ржавчина: токио). Поскольку фьючерсы не являются кооперативными, им требуется планировщик на основе обратных вызовов (даже для фьючерсов на основе опросов требуются обратные вызовы) для выполнения задач блокировки в потоке или пуле процессов. Какие преимущества дает объединение фьючерсов (на уровне библиотеки) с сопрограммами (на уровне языка), как это делают следующие языки: (python: asyncio), (rust: rfc), (ecmascript 6+). По сути, они кажутся противоречивыми решениями одной и той же проблемы.

Я не ищу сравнение «за» и «против», и я не покупаю аргумент, что фьючерсы являются сопрограммами «одним выстрелом». Достаточно взглянуть на ржавчину, которая построила всю структуру событий на основе конечного автомата, используя только фьючерсы Я хочу знать, почему python / asyncio и javascript требуют сопрограмм вместе с фьючерсами. Почему ржавчина планирует добавить сопрограммы в свое будущее? Связано ли это с компоновкой событий? Или неявный стек сопрограмм против явного стека фьючерсов с прохождением продолжения? Не то чтобы я полностью понял этот аргумент, так как и фьючерсы, и сопрограммы реализованы с использованием продолжений ... Или это как-то связано с прямым или косвенным стилем?

1 Ответ

0 голосов
/ 09 сентября 2018

Это разные (хотя и связанные) идеи с разным количеством силы.

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

  • A генератор является более мощным, чем будущее, потому что он может давать несколько раз. Вы можете реализовать фьючерсы поверх генераторов.

  • A сопрограмма является более мощным, чем генератор, потому что он может выбирать, кому уступать, а не только вызывающему. Например, он может уступить другому сопрограмму. Вы можете реализовать генераторы поверх сопрограмм.

Зачем вам использовать менее мощный инструмент, если доступны более мощные? Иногда менее мощный инструмент является правильным инструментом для работы. Полезно статически кодировать инварианты вашей программы, используя типы, потому что это может дать вам уверенность в том, что что-то не может сделать.

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

...