Control structures in programming languages: from goto to algebraic effects
Книга Ксавье Леруа исследует эволюцию управляющих конструкций в языках программирования, от ранних операторов goto до современных алгебраических эффектов. Работа представляет собой историческое путешествие по дизайну языков, уделяя особое внимание механизмам контроля выполнения программ. Книга охватывает структурированное программирование 1960-х, генераторы и корутины в императивных языках, а также продолжения и операторы контроля в функциональных языках.
Книга разделена на четыре части: управляющие конструкции для императивных языков, операторы контроля для функциональных языков, от исключений к алгебраическим эффектам и обработчикам, а также рассуждения о контроле и эффектах. Особую ценность представляют многочисленные примеры кода на разных языках — от Fortran и Algol 60 до OCaml и Haskell. Работа сочетает историю, практические примеры и теорию, предлагая оригинальный сравнительный взгляд на языки программирования и обширное введение в алгебраические эффекты — современную область исследований в PL.
Комментарии (29)
- Критика исключений как "glorified come from", сравнение с POSIX сигналами и setjmp/longjmp.
- Дискуссия о checked исключениях в Java vs подход "ошибки как данные" для ожидаемых сбоев.
- Вопрос производительности алгебраических эффектов и ответ: реализация возможна через монады, оптимизирована в OCaml 5.
- Упоминание Xavier Leroy как автора CompCert, LinuxThreads и ключевой фигуры OCaml/Rocq.
- Шутка про INTERCAL и "come from" как пример необычного синтаксиса.
Simplify your code: Functional core, imperative shell 🔥 Горячее 💬 Длинная дискуссия
Google предлагает разделять код на функциональное ядро и императивную оболочку для упрощения разработки. Функциональное ядро содержит чистую бизнес-логику без побочных эффектов, а императивная оболочка обрабатывает взаимодействие с внешними системами. Такой подход позволяет тестировать логику изолированно и делает код более поддерживаемым. В статье приведен пример кода для отправки уведомлений об окончании подписки, демонстрирующий разницу между смешиванием логики и побочных эффектов и их разделением.
При таком разделении добавление новых функций становится проще - достаточно создать новые чистые функции и переиспользовать существующие. Например, для напоминаний о подписке можно создать функцию generateReminderEmails, используя уже существующую getExpiredUsers. Этот паттерн, впервые описанный Гэри Бернхардтом, помогает создавать более тестируемый, поддерживаемый и адаптивный код, избегая "спагетти" из смешанной логики и побочных эффектов.
Комментарии (170)
- Обсуждение вращается вокруг идеи "functional core, imperative shell" (FCIS) и противоположного ей подхода "generic core, specific shell", а также влияния этих подходов на тестируемость, производительность и читаемость кода.
- Участники обсуждают, что FCIS делает код более тестируемым, но может привести к проблемам с производительностью при работе с большими объемами данных, особенно если язык не поддерживает ленивые коллекции.
- Также обсуждается, что важно разделять логику и эффекты, но пример кода в статье вызывает вопросы, потому что он не демонстрирует лучшие практики, такие как пагинация или фильтрация на уровне базы данных.
- Некоторые участники подчеркивают, что важно не только следовать паттерну, но и использовать здравый смысл, чтобы не плодить сущности, которые не масштабируются, и не создавать ситуаций, где пример кода в статье может быть использован как оправдание для плохого кода.