October 11th, 2012

flow

Как избавиться от динамической типизации

Давно хотел оформить subj в один пост, а сейчас и срачи подоспели в тему:
http://thedeemon.livejournal.com/54732.html
http://belnetmon.livejournal.com/2093044.html
http://metaclass.livejournal.com/735575.html

У меня мнение такое: динамическая типизация вообще не нужна. Она существует исключительно из-за проблем с совмещением разных предметных областей и проблем с нормализацией в традиционных языках со статической системой типов. Однако, проблем решаемых.

Когда в языке с динамической типизацией пишется obj.width = 132, то мы и так заранее знаем, что width всегда int (или что-то ещё известное, в зависимости от архитектуры системы). Нет ситуаций, когда в width должен содержаться экземпляр какого-нибудь HTTPConnection или иной мусор. Однако, width может отсутствовать, если данный obj не используется в ситуациях заведомо требующих наличия width, а используется только там, где width не требуется, или наличие дополнительно проверяется.

Это типичная ситуация для САПРов, где таких width, которые есть или нет, могут быть сотни и тысячи. Обычных product types и sum types оказывается недостаточно. Поэтому в САПРах всегда своя система типов, отличающаяся от системы типов хост-языка. Можно добавлять пользовательские свойства (как строки), хотя не во всех системах можно регистрировать ограничения на их типы (что значением "mywidth" всегда будет целое число). В языках с динамической типизацией об этом вообще не думают, объект является контейнером Map(строка->хзчто). Бардак.

Системное решение такое: вместо случайных строк ключами в контейнере должны быть полноценные identity, а типы хранимых значений должны однозначно соответствовать им. Назовём такой тип контейнера multidomain.

Далее, для обычных структур (product types) мы используем описание самой структуры при трансляции a = ent.width, а для multidomain придётся добавить описания необходимых свойств:
type physical.width = pair float UoM
type ui.width = int
и использовать как
b = ent physical.width // получить значение или ошибку времени выполнения
c = ent maybe ui.width // получить Just значение или Nothing
со строгим контролем типов.

Лёгкость работы с такими типами является одним из приоритетов моих языковых исследований. Однако, хотя и менее красиво/сахарно, подобные решения реализуются и на сегодняшних языках с развитой статической типизацией.

Кроме того, multidomain контейнеры подходят не только для "ад, коровники, энтерпрайз", описаний винтиков и жизненного цикла нефтяной платформы, но и для описаний самих типов данных, включая пользовательские traits.