В компьютерном программировании один из многих способов, которыми языки программирования обычно классифицируются, заключается в том, делает ли система типов языка строго типизированной или слабо типизированной ( слабо типизированной ). Однако нет точного технического определения того, что означают эти термины, и разные авторы расходятся во мнениях относительно подразумеваемого значения терминов и относительного ранжирования «силы» систем типов основных языков программирования.
Как правило, строго типизированный язык имеет более строгие правила типизации во время компиляции , что означает, что во время компиляции более вероятно возникновение ошибок и исключений. Большинство этих правил влияют на присвоение переменных, возвращаемые значения функций, аргументы процедур и вызов функций. Языки с динамической типизацией (где проверка типов происходит во время выполнения ) также могут быть строго типизированными. Обратите внимание, что в языках с динамической типизацией у значений есть типы, а не переменные.
Слабо типизированный язык имеет более свободные правила типизации и может давать непредсказуемые или даже ошибочные результаты или может выполнять неявное преобразование типов во время выполнения. [1] Сторонники динамически типизированных (обычно «слабо типизированных») языков считают, что такие проблемы преувеличены, и полагают, что статическая типизация на самом деле создает экспоненциально больший набор проблем и неэффективности. [2] Другая, но связанная концепция - это скрытая типизация .
История
В 1974 г. Лисков и С. Зиллес определили строго типизированный язык как язык, в котором «всякий раз, когда объект передается от вызывающей функции к вызываемой функции, его тип должен быть совместим с типом, объявленным в вызываемой функции». [3] В 1977 году К. Джексон писал: «В строго типизированном языке каждая область данных будет иметь отдельный тип, и каждый процесс будет определять свои коммуникационные требования в терминах этих типов». [4]
Определения "сильный" или "слабый"
Ряд различных языковых дизайнерских решений упоминается как свидетельство «сильной» или «слабой» типизации. Многие из них более точно понимать как наличие или отсутствие безопасности типа , безопасность памяти , статическая проверка типа или динамическая проверка типа .
«Строгая типизация» обычно относится к использованию типов языка программирования для того, чтобы фиксировать инварианты кода и обеспечивать его правильность, а также определенно исключать определенные классы ошибок программирования. Таким образом, для достижения этих целей используется множество дисциплин «строгой типизации».
Неявные преобразования типов и "каламбур типов"
Некоторые языки программирования позволяют легко использовать значение одного типа, как если бы оно было значением другого типа. Иногда это называют «слабой типизацией».
Например, Ааз Марух замечает, что « принуждение происходит, когда у вас есть статически типизированный язык, и вы используете синтаксические особенности языка для принудительного использования одного типа, как если бы это был другой тип (рассмотрите обычное использование void * в C Принуждение обычно является признаком слабой типизации. С другой стороны, преобразование создает совершенно новый объект соответствующего типа ". [5]
В качестве другого примера GCC описывает это как каламбур типов и предупреждает, что это нарушит строгий псевдоним . Тиаго Мачейра обсуждает несколько проблем, которые могут возникнуть, когда каламбур типов заставляет компилятор делать несоответствующие оптимизации . [6]
Существует множество примеров языков, допускающих неявное преобразование типов , но безопасным для типов способом. Например, и C ++, и C # позволяют программам определять операторы для преобразования значения из одного типа в другой семантически значимым образом. Когда компилятор C ++ встречает такое преобразование, он обрабатывает операцию как вызов функции. Напротив, преобразование значения в тип C void * - небезопасная операция, невидимая для компилятора.
Указатели
Некоторые языки программирования предоставляют указатели, как если бы они были числовыми значениями, и позволяют пользователям выполнять с ними арифметические операции. Эти языки иногда называют «слабо типизированными», поскольку арифметика с указателями может использоваться для обхода системы типов языка.
Непомеченные союзы
Некоторые языки программирования поддерживают немаркированные объединения , которые позволяют рассматривать значение одного типа, как если бы оно было значением другого типа.
Статическая проверка типов
В Лука Карделл статью «ы полнотиповым программирования , [7] „сильная система типа“описываются как тот , в котором нет никакой возможности непроверенного ошибки типа во время выполнения. В других текстах отсутствие неконтролируемых ошибок времени выполнения называется безопасностью или безопасностью типов ; В ранних статьях Тони Хора это называется безопасностью собственности . [8]
Динамическая проверка типов
В некоторых языках программирования нет статической проверки типов. На многих таких языках легко писать программы, которые были бы отклонены большинством статических средств проверки типов. Например, переменная может хранить либо число, либо логическое значение «false».
Различия между языками программирования
Обратите внимание, что некоторые из этих определений противоречивы, другие просто концептуально независимы, а третьи являются частными случаями (с дополнительными ограничениями) других, более «либеральных» (менее строгих) определений. Из-за большого расхождения между этими определениями можно защитить утверждения о том, что большинство языков программирования являются либо строго, либо слабо типизированными. Например:
- Java , Pascal , Go , Ada и C требуют, чтобы все переменные имели объявленный тип, и поддерживают использование явного приведения арифметических значений к другим арифметическим типам. Иногда говорят, что Java, C #, Ada и Pascal имеют более строгую типизацию, чем C, что, вероятно, основано на том факте, что C поддерживает больше видов неявных преобразований, а C также позволяет явно приводить значения указателя, в то время как Java и Pascal не. Сама Java может считаться более строго типизированной, чем Паскаль, поскольку способы обхода системы статических типов в Java контролируются системой типов виртуальной машины Java . C # и VB.NET похожи на Java в этом отношении, хотя они позволяют отключать динамическую проверку типов, явно помещая сегменты кода в «небезопасный контекст». Система типов Паскаля была описана как «слишком сильная», потому что размер массива или строки является частью ее типа, что очень усложняет некоторые задачи программирования. [9]
- Smalltalk , Perl , Ruby , Python и Self являются "строго типизированными" в том смысле, что ошибки ввода предотвращаются во время выполнения и они не выполняют неявное преобразование типов , но эти языки не используют статическую проверку типов: компилятор не проверяет или обеспечить соблюдение правил ограничения типа. Термин « утиная типизация» теперь используется для описания парадигмы динамической типизации, используемой языками этой группы.
- Все языки семейства Lisp являются «строго типизированными» в том смысле, что ошибки ввода предотвращаются во время выполнения. Некоторые диалекты Lisp, такие как Common Lisp или Clojure, действительно поддерживают различные формы объявлений типов [10], а некоторые компиляторы ( CMUCL [11] и родственные) используют эти объявления вместе с выводом типа для обеспечения различных оптимизаций, а также ограниченных форм проверки типов во время компиляции.
- Стандартные ML , F # , OCaml , Haskell и Rust проверяются статически, но компилятор автоматически определяет точный тип для большинства значений.
- Visual Basic - это гибридный язык. В дополнение к переменным с объявленными типами также можно объявить переменную типа данных «Вариант», которая может хранить данные любого типа. Его неявные преобразования довольно либеральны, например, можно суммировать строковые варианты и передавать результат в целочисленную переменную. Visual Basic слабо типизирован.
- Ассемблер , Forth можно охарактеризовать как нетипизированный . Нет проверки типа; программист должен гарантировать, что данные, передаваемые функциям, имеют соответствующий тип. Любое требуемое преобразование типа является явным.
- Tcl можно охарактеризовать как явно типизированный: тип значения определяется исключительно его представлением, оценка которого зависит от контекста.
По этой причине авторы, которые хотят однозначно писать о системах типов, часто избегают термина «строгая типизация» в пользу конкретных выражений, таких как « безопасность типов ».
Смотрите также
- Тип данных включает более подробное обсуждение вопросов ввода
- Сравнение языков программирования
- Скрытый набор текста
- Безопасность памяти
- Дизайн по контракту (строгая типизация как неявная форма контракта)
- Безопасность типов
- Система типов
Рекомендации
- ^ «CS1130. Переход к объектно-ориентированному программированию. - Весна 2012 - самостоятельная версия» . Корнельский университет, факультет компьютерных наук. 2005. Архивировано из оригинала на 2005 . Проверено 23 ноября 2015 .
- ^ «Неоправданная эффективность динамического набора текста для практических программ» . Vimeo . 12 сентября 2013 . Проверено 21 марта 2021 года .
- ^ Лисков, Б; Зиллес, S (1974). «Программирование с абстрактными типами данных». Уведомления ACM SIGPLAN . 9 (4): 50–59. CiteSeerX 10.1.1.136.3043 . DOI : 10.1145 / 942572.807045 .
- ^ Джексон, К. (1977). Параллельная обработка и модульное построение программного обеспечения . Дизайн и реализация языков программирования . Конспект лекций по информатике. 54 . С. 436–443. DOI : 10.1007 / BFb0021435 . ISBN 3-540-08360-X.
- ^ Ааз. «Печатание: сильное или слабое, статическое или динамическое» . Проверено 16 августа 2015 года .
- ^ «Наблюдение за типом и строгий псевдоним - Блог Qt» . Блог Qt . Дата обращения 18 февраля 2020 .
- ^ Лука Карделли, "Типовое программирование"
- ↑ Hoare, CAR 1974. Подсказки по дизайну языков программирования. В области надежности компьютерных систем , под ред. C. Bunyan. Vol. 20 с. 505–534.
- ^ InfoWorld . 1983-04-25 . Проверено 16 августа 2015 года .
- ^ «CLHS: Глава 4» . Проверено 16 августа 2015 года .
- ^ «Руководство пользователя CMUCL: компилятор» . Архивировано из оригинала 8 марта 2016 года . Проверено 16 августа 2015 года .