12 1.1. Типы в информатике
Даже внутри науки информатики существуют две различных ветви, где изучаются системы типов.
Более практическая, где исследуются приложения к языкам программирования, является основной
темой этой книги. Более абстрактная ветвь изучает соответствия между различными «чистыми типи-
зированными лямбда-исчислениями» и разновидностями логики, через соответствие Карри-Ховарда
(§9.4). В этих сообществах используются похожие понятия, системы записи и методы, однако имеют-
ся важные различия в ориентации. Например, исследования по типизированному лямбда-исчислению
обычно имеют дело с системами, где гарантируется завершение для всякого правильно типизирован-
ного вычисления, в то время как большинство языков программирования жертвуют этим свойством,
чтобы иметь возможность работать с инструментами вроде рекурсивных функций.
Еще одним важным свойством предложенного определения является упоминание классификации
термов — синтаксических составляющих, — в соответствии со значениями, которые они породят, бу-
дучи вычисленными. Систему типов можно рассматривать как статическое приближение к поведению
программы во время выполнения. (Более того, типы термов обычно вычисляются композиционально,
то есть тип выражения зависит только от типов его подвыражений.)
Иногда слово «статический» добавляется явным образом — например, говорят о «языках програм-
мирования со статической типизацией», — чтобы отличить анализ, производимый при компиляции,
который мы рассматриваем здесь, от динамических или латентных типов в языках вроде Scheme
(Sussman and Steele 1975; Kelsey, Clinger and Rees, 1998; Dybvig 1996), где при помощи тегов типов
во время выполнения различаются различные виды структур в куче. Термин «динамическая типиза-
ция», по нашему мнению, неверен (его следовало бы заменить на «динамические проверки»), но такое
употребление является стандартным.
Будучи статическими, системы типов по необходимости консервативны: они способны однозначно
доказать отсутствие определенных нежелательных видов поведения, но не могут доказать их наличие,
и, следовательно, иногда вынуждены отвергать программы, которые на самом деле при выполнении
ведут себя подобающим образом. Например, программа
if <сложная проверка> then S else <ошибка типа>
будет отвергнута как неверно типизированная, даже если сложная проверка всегда выдает значение
истина, поскольку статический анализ неспособен это заметить. Противоречие между консервативно-
стью и выразительностью — важный фактор при разработке систем типов. Желание позволить как
можно большему числу программ проходить проверку через присвоение более точно определенных
типов их выражениям служит основной движущей силой в нашей научной дисциплине.
Подобным образом, относительно незамысловатые виды анализа, воплощенные в большинстве си-
стем типов, неспособны запретить всякое нежелательное поведение в программах; они гарантируют
только то, что программы свободны от определенных видов ошибок. Например, большинство систем
типов могут статически убедиться, что аргументами элементарных арифметических операций всегда
служат числа, что объект-получатель при вызове метода всегда имеет соответствующий метод, и т. п.,
но не могут проверить, что второй аргумент в операции деления не равен нулю, или что индексы при
обращениях к массиву не выходят за границы.
Виды плохого поведения, которые в данном языке могут быть исключены при помощи типов, часто
называют ошибками типов времени выполнения. Важно помнить, что набор таких ошибок зависит
от выбора языка: несмотря на то, что между ошибками времени выполнения в разных языках есть
существенное пересечение, в принципе каждая система типов сама указывает, какие именно ошибки
она намерена предотвратить. Безопасность (или корректность) системы типов должна определяться
по отношению к её собственному набору ошибок времени выполнения.
Виды неправильного поведения, выявляемые через анализ типов, не ограничиваются низкоуровне-
выми ошибками вроде вызова несуществующих методов: системы типов используют также для обеспе-
чения высокоуровневой модульности и для защиты целостности абстракций, определяемых пользова-
телем. Нарушения сокрытия информации, например, прямое обращение к полям объекта, чья реали-
зация должна быть абстрактной, являются ошибками типа в той же мере, как и, скажем, обращение к
целому числу как к указателю, приводящее к краху работы программы.
Процедуры проверки типов обычно встроены в компиляторы или компоновщики. Следовательно,
они должны быть способны выполнять свою работу автоматически, без ручного вмешательства или
взаимодействия с программистом, — т. е., они должны представлять собой вычислительно разреши-
rev. 104