bythe.net
← К ленте
Новинки

Elixir обзавёлся системой типов, и старый код не нужно переписывать

Теоретико-множественные типы выводятся компилятором без аннотаций и уже ловят ошибки в реальных проектах. Как это работает и что изменится для разработчиков.

Как Elixir пришёл к типам

Elixir — динамический язык, и долгие годы его создатель Жозе Валим отвечал на вопросы о типах одинаково: это не стоит усилий. Dialyzer, инструмент из мира Erlang, находил часть ошибок, но работал медленно, давал малопонятные сообщения и требовал аннотаций, которые никто не любил писать.

В 2022 году Валим совместно с исследователями Джузеппе Кастаньей и Гийомом Дюбоком начал работу над системой на основе теоретико-множественных типов. Идея в том, что типы описываются как множества значений с операциями объединения, пересечения и отрицания, и это хорошо ложится на динамический язык, где функция может принимать «целое число или атом :infinity».

Что уже работает

С версии 1.17 компилятор начал выводить типы для базовых конструкций и предупреждать об очевидных ошибках: обращение к несуществующему полю структуры, сравнение значений несовместимых типов, недостижимая ветка case. В 1.18 вывод распространился на вызовы функций внутри модуля, а в 1.19 и 1.20 на вызовы между модулями и на анонимные функции.

Предупреждения выглядят так:

warning: incompatible types given to Kernel.+/2:
user.age + "1"
given types:
integer() + binary()

Ключевое свойство: аннотации не требуются. Типы выводятся из кода, который уже написан, включая сопоставление с образцом и охранные выражения. Существующие проекты получают проверки просто после обновления Elixir.

Постепенность

Система типов градуальная: там, где компилятор не может вывести тип, он использует dynamic(), и дальнейшие проверки не мешают. Это означает отсутствие ложных срабатываний как цель проектирования. Если компилятор выдал предупреждение, в коде почти наверняка ошибка.

Это отличает подход от TypeScript, где any быстро распространяется и ослабляет проверки, и от Dialyzer, где осторожный анализ пропускал реальные ошибки.

Что дальше

В планах явные аннотации типов для функций, которые заменят @spec, и проверка типов для протоколов и поведений. Сроки команда не называет, и это осознанно: каждый шаг выкатывается только когда не ломает существующий код.

Почему это важно

Типизация динамических языков обычно означает новый диалект, который нужно принимать целиком, как TypeScript или Sorbet. Elixir идёт другим путём: компилятор становится умнее, а язык остаётся прежним. Если подход сработает до конца, это будет редкий пример того, как добавить типы в язык без раскола сообщества.

Войти, чтобы оценить материал

Комментарии

Войти, чтобы оставить комментарий