Оси систем типов
- title
- Оси систем типов
- type
- concept
- summary
- Статическая/динамическая (время проверки) и сильная/слабая (объём неявных приведений) - независимые измерения
- tags
- programming-languages, type-systems
- created
- 2026-04-25
- updated
- 2026-07-29
- lang
- ru
- translation_of
- type-system-axes
- source_updated
- 2026-07-29
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
Системы типов различаются по двум независимым измерениям. Их смешение - или подмена размытыми терминами вроде "строгая" - приводит к спорам, где собеседники не согласны друг с другом по поводу того, что ни один из них даже не назвал.
Статическая или динамическая - когда проверяются типы
Статическая типизация проверяет типы по исходному коду без запуска программы. Компилятор или анализатор отклоняет код, не прошедший проверку; программа ни при каких условиях не выполняется в состоянии, где в проверенных местах могла бы возникнуть ошибка типа.
Динамическая типизация проверяет типы во время выполнения. Каждое значение несёт тег типа, который среда исполнения проверяет по мере необходимости - при попытке выполнить операцию, при диспетчеризации метода или при распаковке значения.
Это отличается от бестиповой модели (untyped), где проверки типов не происходят вовсе - ни статически, ни динамически. Ассемблер бестиповой. Динамически типизированный язык полноценно типизирован; проверки в нём просто выполняются позже.
Сильная или слабая - насколько допустимо неявное приведение
Сильная типизация означает, что язык отказывается неявно преобразовывать типы друг в друга. Операции, смешивающие разные типы, либо завершаются ошибкой, либо требуют явного приведения.
Слабая типизация означает, что язык будет незаметно приводить типы через границы, чтобы операция выполнилась: адресная арифметика над сырыми байтами, числовое расширение с изменением знаковости, приведение строки к числу в операторах сравнения.
Это измерение касается неявности преобразований, а не самого наличия типов.
Обе оси ортогональны
Часто ошибочно полагают, будто статическая типизация подразумевает сильную, а динамическая - слабую. В четырёхклеточной матрице примеры есть для каждого квадранта:
- Статическая + слабая: C. Компилятор проверяет типы статически, но позволяет интерпретировать
char*какint*и выполнять над ним арифметические операции. - Статическая + сильная: Haskell, Rust. Проверка во время компиляции без неявных преобразований.
- Динамическая + сильная: Python. Типы проверяются во время выполнения, но
"3" + 4приводит к ошибке, а не к"34"или7. - Динамическая + слабая: JavaScript, PHP. Проверки во время выполнения, но
"3" + 4 === "34"и"3" * 4 === 12.
Почему термины "строгая" и "нестрогая" всё запутывают
В дискуссиях термины "строгая типизация" (strict) или "нестрогая типизация" (loose) часто ставят вместо одного из четырёх стандартных понятий. Восстановить смысл при такой подмене невозможно: читатель не может понять, означает ли "строгая" статическую, сильную или обе сразу. Льюис Кэмпбелл (Lewis Campbell) считает, что такие термины придумывают люди, которые не освоили двухосевую модель и хотят свести всё к одному ползунку - которого в реальности нет.
Зависимые типы находятся на дальнем конце статической оси: свойства, проверяемые до запуска программы, могут быть произвольными, а zstd-lean-proof-automation показывает, чего на практике стоит доказательство одного из них - простоты числа или уникальной достижимости.
Исходный пост описан в type-systems-vocabulary. sqlite-strict-tables - пример оси сильной/слабой типизации (приведения типов) в базах данных: гибкая типизация SQLite по умолчанию приводит значения к сродству типов (affinity) колонки, а таблицы STRICT это отключают; "strict" здесь обозначает именно ось приведения, а не статическую/динамическую типизацию.