Comments 10
Спасибо. Одно время игрался с этим в проде, когда на хаскелле работал. Нужен был tcp сервер со сложной логикой инициализации/закрытия соединения. Ну и там на cps в одной итерации было написано. Короче, мне читаемость не понравилась - переписал в итоге типа defer на writer монаде.
Это популярное развлечение - переписать факториал на разных функциональных паттернах, но интересно какую задачу CPS решает лучше чем любой другой подход.
В cps можно жонглировать и вести/приостанавливать сразу несколько потоков управления. Как с корутинами, но в языке без корутин.
Ещё есть интересная идея, что contination можно несколько раз продолжить с одного и того же места. Тогда поток исполнения вместо линейного превращается в что-то типа дерева.
Я игрался с ними реалировав мультизадачность. Потом участвовал в проекте на Scheme, где продолжения использовались для нелокального выхода, но была проблема с производительностью, некоторые места пришлось перписать на исключения.
Сейчас продолжения меня интерсуют тем, что используются в алгебраических эффектах, которые я рассматриваю как способ реализовать capabilities-based security.
было бы интересно посмотреть на реализацию мультизадачности. Может быть как нибудь опишите её здесь?
Прошло много лет, но все-таки я ее нашел.
благодарю, я помотрел. это же невытесняющая многозадачность. да любопытно было посмотреть, я почему то подумал что будет не кооперативная, а вытесняющая многозадачность. Чтобы её реализовывать надо подменить все(или значительную их часть) базовые функции, функциями вычисляющими тайминг, и при необходимости переключать задачи. Но это затратно, и коопреративная многзадачность пожалуй будет работать лучше. Но в принципе и с вытесняющей многозадачность можно так же поиграться.
CPS позволяет синтаксически разворачивать функциональный вызов, то есть, например, совместно оптимизировать разные шаги рекурсии. Но это больше для компилятора развлечение, чем для человека.
пример с вызовом двух call/cc вызывает лёгкую головную боль, мозг при этом переходит в состояние прострации. между тем, если бы вы продемонстриовали более простой пример, как переходный к приведённому, вероятно он бы стал понятнее.
((call/cc (lambda (k) (display "in lambda 1 ") display)) "twice ") ;; #<void>
;;in lambda 1 twice
Добрый день!
Существует ещё концепция алгебраических эффектов с обработчиками.
Они позволяют добавлять в язык такие функции как исключения и async в виде библиотек.
Алгебраические эффекты есть в Koka (https://koka-lang.github.io) и Flix (flix.dev).
Это новая и очень интересная тема.
Возвратиться или продолжить: поговорим про continuations