Теория языков программирования
Type-safe API Design
Mars Climate Orbiter разбился о Марс в 1999 потому что одна команда использовала метрические единицы, другая - имперские. $327 миллионов. Phantom types для единиц измерения предотвратили бы эту ошибку на уровне компилятора. Make impossible states impossible - это не академика, это инженерия.
- **Elm Html msg**: тип Html гарантирует что XSS невозможен - нельзя вставить string напрямую как HTML. Phantom type msg гарантирует корректную типизацию event handlers
- **F# units of measure**: встроенные phantom types для физических единиц. Используется в финансовых системах для предотвращения путаницы валют
- **Rust API design**: tokio::sync::Mutex<T> vs std::sync::Mutex<T> - разные типы, нельзя случайно использовать blocking mutex в async context
Phantom Types
Phantom type - тип-параметр который не присутствует в данных, только в типе. Используется для добавления compile-time ограничений без runtime overhead. Классический пример: отслеживание единиц измерения, состояний, уровней прав.
Почему phantom types не имеют runtime overhead?
Type-safe Builder Pattern
Type-safe builder использует phantom types для отслеживания какие поля установлены. Компилятор не позволяет вызвать build() пока не установлены все обязательные поля. Ошибка 'missing required field' становится compile error.
Что делает type-safe builder принципиально лучше обычного Builder паттерна?
Typestate Programming
Typestate - техника кодирования состояний объекта в его типе. Операции доступны только в правильных состояниях. Файл: Open -> Read/Write -> Closed. Нельзя читать закрытый файл - compile error, не runtime error.
Typestate кодирует состояния объекта в типах. Что это даёт по сравнению с runtime проверками?
Branded Types и Newtypes
Branded types (newtype wrapper) - обёртка над примитивом, создающая отдельный тип. UserId, OrderId - оба Int, но нельзя перепутать. SQL injection prevention: RawInput vs SanitizedInput - нельзя передать сырой ввод туда где ожидается sanitized.
Phantom types и branded types - академические техники без практической пользы
Elm использует phantom types для безопасного HTML: Html msg тип предотвращает XSS на уровне компилятора. NASA использует размерные типы для предотвращения ошибок типа Mars Climate Orbiter
Mars Climate Orbiter ($327M) разбился из-за перепутанных единиц (фунт-сила vs ньютон). Phantom types для единиц измерения предотвратили бы это на этапе компиляции
Почему newtype в Haskell называется 'zero-cost'?
Итоги
- **Phantom types**: тип-параметр только в типах, не в данных. Zero-cost. Для единиц измерения, состояний, прав доступа
- **Type-safe Builder**: phantom types отслеживают установленные поля. build() без обязательных полей - compile error
- **Typestate**: состояния объекта в типах. execute() без login() - compile error. Impossible state = impossible to compile
- **Branded/Newtype**: UserId ≠ OrderId хотя оба Int. RawInput ≠ SanitizedInput. SQL injection prevention через типы
Связанные темы
Type-safe API использует продвинутые возможности систем типов:
- Функциональное программирование — Newtype pattern и phantom types из Haskell переносятся в другие языки
- Theorem provers — Dependent types в Idris/Agda - следующий уровень: свойства кодируются в типах
Вопросы для размышления
- Typestate делает невозможные состояния невозможными. Но что происходит когда состояние зависит от runtime данных (авторизован ли пользователь)? Как typestate работает с этим?
- Elm гарантирует отсутствие XSS через систему типов. TypeScript пытается сделать то же через DomSanitizer. Почему compile-time гарантии Elm сильнее runtime проверок TypeScript?
- Branded types в TypeScript - workaround, не настоящие phantom types (escape через as). Как это ограничение влияет на надёжность подхода?