Сильная и слабая типизация

Системы типов языка программирования

В компьютерном программировании один из многих способов, которым языки программирования в разговорной речи классифицируются, заключается в том, делает ли система типов языка строго типизированной или слабо типизированной ( свободно типизированной ). Однако не существует точного технического определения того, что означают эти термины, и разные авторы расходятся во мнениях относительно подразумеваемого значения терминов и относительного ранжирования «силы» систем типов основных языков программирования. [1] По этой причине авторы, желающие писать о системах типов однозначно, часто избегают терминов «строгая типизация» и «слабая типизация» в пользу конкретных выражений, таких как « безопасность типов ».

Как правило, строго типизированный язык имеет более строгие правила типизации во время компиляции , что подразумевает, что ошибки и исключения с большей вероятностью возникнут во время компиляции. Большинство этих правил затрагивают назначение переменных, возвращаемые значения функций, аргументы процедур и вызов функций. Динамически типизированные языки (где проверка типов происходит во время выполнения ) также могут быть строго типизированными. В динамически типизированных языках типы имеют значения, а не переменные.

Слабо типизированный язык имеет более свободные правила типизации и может давать непредсказуемые или даже ошибочные результаты или может выполнять неявное преобразование типов во время выполнения. [2] Другая, но связанная концепция — скрытая типизация .

История

В 1974 году Барбара Лисков и Стивен Зиллес определили строго типизированный язык как язык, в котором «всякий раз, когда объект передается из вызывающей функции в вызываемую функцию, его тип должен быть совместим с типом, объявленным в вызываемой функции». [3] В 1977 году К. Джексон писал: «В строго типизированном языке каждая область данных будет иметь отдельный тип, и каждый процесс будет заявлять свои требования к коммуникации в терминах этих типов». [4]

Определения «сильный» или «слабый»

Ряд различных решений по проектированию языка упоминаются как доказательства «сильной» или «слабой» типизации. Многие из них более точно понимаются как наличие или отсутствие безопасности типов , безопасности памяти , статической проверки типов или динамической проверки типов .

«Строгая типизация» обычно относится к использованию типов языка программирования для того, чтобы как захватить инварианты кода , так и гарантировать его корректность и определенно исключить определенные классы ошибок программирования. Таким образом, существует множество дисциплин «строгой типизации», используемых для достижения этих целей.

Неявные преобразования типов и «каламбуры типов»

Некоторые языки программирования позволяют легко использовать значение одного типа, как если бы это было значение другого типа. Иногда это называют «слабой типизацией».

Например, Ааз Маруч замечает, что « Принуждение происходит, когда у вас статически типизированный язык, и вы используете синтаксические особенности языка, чтобы принудительно использовать один тип, как если бы это был другой тип (рассмотрите распространенное использование void* в C ). Принуждение обычно является симптомом слабой типизации. Преобразование, с другой стороны, создает совершенно новый объект соответствующего типа». [5]

В качестве другого примера GCC описывает это как тип-каламбур и предупреждает, что это нарушит строгое алиасинг . Тиаго Масиейра обсуждает несколько проблем, которые могут возникнуть, когда тип-каламбур заставляет компилятор выполнять ненадлежащие оптимизации . [6]

Существует множество примеров языков, которые допускают неявные преобразования типов , но безопасным для типов образом. Например, как C++, так и C# позволяют программам определять операторы для преобразования значения из одного типа в другой с четко определенной семантикой. Когда компилятор C++ сталкивается с таким преобразованием, он обрабатывает операцию как вызов функции. Напротив, преобразование значения в тип C void* является небезопасной операцией, которая невидима для компилятора.

Указатели

Некоторые языки программирования выставляют указатели как числовые значения и позволяют пользователям выполнять арифметические действия с ними. Такие языки иногда называют «слабо типизированными», поскольку арифметика указателей может использоваться для обхода системы типов языка.

Немаркированные профсоюзы

Некоторые языки программирования поддерживают немаркированные объединения , которые позволяют рассматривать значение одного типа так, как если бы это было значение другого типа.

Статическая проверка типов

В статье Луки Карделли «Типовое программирование » [7] «система сильного типа» описывается как система, в которой нет возможности неконтролируемой ошибки типа во время выполнения. В других работах отсутствие неконтролируемых ошибок типа во время выполнения называется безопасностью или безопасностью типа ; ранние работы Тони Хоара называют это свойство безопасностью [8] .

Различия в языках программирования

Некоторые из этих определений противоречивы, другие просто концептуально независимы, а третьи являются частными случаями (с дополнительными ограничениями) других, более "либеральных" (менее сильных) определений. Из-за большого расхождения между этими определениями можно защищать утверждения о большинстве языков программирования, что они либо сильно, либо слабо типизированы. Например:

  • Java , Pascal , Ada и C требуют , чтобы переменные имели объявленный тип, и поддерживают использование явных приведений арифметических значений к другим арифметическим типам. Иногда говорят, что Java, C#, Ada и Pascal более строго типизированы, чем C, потому что C поддерживает больше видов неявных преобразований и позволяет явно приводить значения указателей , в то время как Java и Pascal этого не делают. Java можно считать более строго типизированным, чем Pascal, поскольку методы обхода статической системы типов в Java контролируются системой типов виртуальной машины Java . C# и VB.NET похожи на Java в этом отношении, хотя они позволяют отключать динамическую проверку типов, явно помещая сегменты кода в «небезопасный контекст». Система типов Pascal была описана как «слишком строгая», потому что размер массива или строки является частью его типа, что делает некоторые задачи программирования очень сложными. Однако Delphi исправляет эту проблему. [9] [10]
  • Smalltalk , Ruby , Python и Self являются «строго типизированными» в том смысле, что ошибки при типизации предотвращаются во время выполнения, и они делают мало неявного преобразования типов , но эти языки не используют статическую проверку типов: компилятор не проверяет и не применяет правила ограничения типов. Термин « утиная типизация» теперь используется для описания парадигмы динамической типизации, используемой языками этой группы.
  • Семейство языков Lisp является «строго типизированным» в том смысле, что ошибки при типизации предотвращаются во время выполнения. Некоторые диалекты Lisp, такие как Common Lisp или Clojure, поддерживают различные формы объявлений типов [11] , а некоторые компиляторы ( CMU Common Lisp (CMUCL) [12] и родственные) используют эти объявления вместе с выводом типов для включения различных оптимизаций и ограниченных форм проверок типов во время компиляции.
  • Стандартные ML , F# , OCaml , Haskell , Go и Rust статически проверяют типы, но компилятор автоматически выводит точный тип для большинства значений.
  • Язык ассемблера и Форт можно охарактеризовать как нетипизированный . Проверка типов отсутствует; программист должен убедиться, что данные, переданные функциям, имеют соответствующий тип.

Смотрите также

Ссылки

  1. ^ "Что нужно знать перед обсуждением систем типов | Овидий [blogs.perl.org]". blogs.perl.org . Получено 2023-06-27 .
  2. ^ "CS1130. Переход к объектно-ориентированному программированию. – Весна 2012 г. – версия для самостоятельного изучения". Корнелльский университет, кафедра компьютерных наук. 2005. Архивировано из оригинала 23.11.2015 . Получено 23.11.2015 .{{cite web}}: CS1 maint: бот: исходный статус URL неизвестен ( ссылка )
  3. ^ Лисков, Б.; Зиллес, С. (1974). «Программирование с абстрактными типами данных». ACM SIGPLAN Notices . 9 (4): 50–59 . CiteSeerX 10.1.1.136.3043 . doi :10.1145/942572.807045. 
  4. ^ Джексон, К. (1977). "Параллельная обработка и модульное построение программного обеспечения". Проектирование и реализация языков программирования . Конспект лекций по информатике. Том 54. С.  436–443 . doi :10.1007/BFb0021435. ISBN 3-540-08360-X.
  5. ^ Aahz. "Typing: Strong vs. Weak, Static vs. Dynamic" . Получено 16 августа 2015 г. .
  6. ^ "Type-punning and strict-aliasing - Qt Blog". Qt Blog . Получено 18 февраля 2020 г. .
  7. ^ Лука Карделли, «Типовое программирование»
  8. ^ Hoare, CAR 1974. Советы по проектированию языков программирования. В Computer Systems Reliability , под ред. C. Bunyan. Т. 20, стр. 505–534.
  9. ^ InfoWorld. 1983-04-25 . Получено 16 августа 2015 г.
  10. ^ Керниган, Брайан (1981). «Почему Паскаль не мой любимый язык программирования». Архивировано из оригинала 2012-04-06 . Получено 2011-10-22 .
  11. ^ "CLHS: Глава 4" . Получено 16 августа 2015 г.
  12. ^ "CMUCL User's Manual: The Compiler". Архивировано из оригинала 8 марта 2016 года . Получено 16 августа 2015 года .
Взято с "https://en.wikipedia.org/w/index.php?title=Сильная_и_слабая_печать&oldid=1265041111"