Теория языков программирования
Функциональное программирование
Код без мутаций, без null pointer exceptions, без race conditions. Звучит как утопия - но именно это даёт функциональное программирование. И это не академическая теория: Haskell используется в Cardano blockchain, OCaml в Jane Street (торги на $20 млрд/день), Clojure в Nubank (50 млн клиентов).
- **Jane Street**: весь trading в OCaml - иммутабельность исключает класс багов, критических при управлении миллиардами долларов
- **WhatsApp**: Erlang (функциональный язык) - 2 млн соединений на один сервер, 50 инженеров на 450 млн пользователей
- **Elm**: фронтенд-язык без runtime exceptions в продакшене - иммутабельная архитектура делает impossible states literally impossible
- **React**: функциональные компоненты и иммутабельный state (useState) - прямое влияние ФП на mainstream JavaScript
Иммутабельность
Иммутабельность означает, что данные не изменяются после создания. Вместо мутации создаётся новая версия структуры данных. Это устраняет целый класс багов - race conditions, неожиданные изменения состояния, проблемы с кешированием.
Persistent data structures в функциональных языках - как они избегают O(n) копирования при каждом обновлении?
Функции высшего порядка
Функции высшего порядка (HOF) - функции, которые принимают функции как аргументы или возвращают функции. Это основной инструмент абстракции в ФП. `map`, `filter`, `fold` - канонические примеры.
Что такое каррирование (currying)?
Монады
Монада - это тип с двумя операциями: `return` (обернуть значение) и `bind` (>>=) (применить функцию к обёрнутому значению). Монада - паттерн для цепочки вычислений с побочным контекстом: Maybe - для ошибок, IO - для side effects, State - для состояния.
Какую проблему решает Maybe монада?
Теория категорий в ФП
Теория категорий - математическая основа ФП. В Haskell: типы - объекты, функции - морфизмы. Functor, Applicative, Monad - не просто интерфейсы, а алгебраические структуры с законами, которые можно проверять.
Практическая ценность: законы функторов и монад - это тестируемые свойства. Если тип нарушает закон identity или composition - абстракция сломана. QuickCheck может автоматически проверить законы для любого типа.
Монаду нельзя понять без глубокого знания теории категорий
Монаду можно использовать эффективно, зная только: return/pure, bind(>>=), и три закона
Теория категорий даёт понимание почему это работает, но для практики достаточно интерфейса. Большинство Haskell-программистов используют монады годами до изучения теории категорий
Что гарантируют законы функтора?
Ключевые идеи
- **Иммутабельность** устраняет целый класс багов. Persistent data structures делают это эффективным через структурное разделение - O(log n), не O(n)
- **HOF и каррирование** - основной инструмент абстракции: функции как значения первого класса, частичное применение, point-free стиль
- **Монады** - паттерн для цепочки вычислений с контекстом. Maybe, Either, IO, State решают разные аспекты без вложенных if-проверок
- **Законы функторов и монад** - проверяемые алгебраические свойства, мощнее unit тестов
Связанные темы
ФП пронизывает современные языки:
- IO монады и side effects — IO монада - как Haskell управляет side effects через систему типов
- Алгебраические эффекты — Algebraic effects - следующий шаг после монад для структурирования эффектов
Вопросы для размышления
- Если иммутабельность так хороша, почему Rust выбрал mut-по-умолчанию-отключено вместо полной иммутабельности как в Haskell?
- Монада IO в Haskell изолирует side effects в системе типов. Как бы вы смоделировали подобную изоляцию в TypeScript?
- Почему fmap id должно быть равно id? Что семантически сломается, если этот закон нарушен?