В чем разница между строго типизированным языком и статически типизированным языком?

Кроме того, подразумевается ли другое?

Ответ 1

В чем разница между строго типизированным языком и статически типизированным языком?

Статически типизированный язык имеет систему типов, которая проверяется во время компиляции реализацией (компилятор или интерпретатор). Проверка типа отклоняет некоторые программы, и программы, которые проходят проверку, обычно приходят с некоторыми гарантиями; например, компилятор гарантирует не использовать целочисленные арифметические инструкции для чисел с плавающей запятой.

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

Статический и динамический

Противоположность статически типизированной "динамически типизирована", что означает, что

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

Например, Lua, динамически типизированный язык, имеет тип строки, тип номера и тип Boolean, среди прочих, В Lua каждое значение относится к одному типу, но это не является обязательным требованием для всех динамически типизированных языков. В Lua допустимо объединить две строки, но недопустимо конкатенировать строку и булево значение.

Сильный против слабых

Противоположность "строго типизирована" "слабо типизирована", что означает, что вы можете обойти систему типов. C, как известно, слабо типизирован, потому что любой тип указателя конвертируется в любой другой тип указателя просто путем литья. Паскаль должен был быть строго типизирован, но надзор в дизайне (незаписанные варианты записей) вводил лазейку в систему типов, поэтому технически она слабо типизирована. Примеры действительно сильно типизированных языков включают CLU, Standard ML и Haskell. Стандарт ML фактически подвергся нескольким ревизиям для устранения лазеек в системе типов, которые были обнаружены после широко распространенного языка.

Что здесь происходит?

В целом, оказывается, не так полезно говорить о "сильных" и "слабых". Независимо от того, имеет ли система типа лазейка меньшее значение, чем точное количество и характер лазеек, насколько они могут возникнуть на практике и каковы последствия использования лазейки. На практике лучше избегать терминов "сильный" и "слабый" вообще, потому что

  • Любители часто объединяют их со "статическими" и "динамическими".

  • По-видимому, "слабое типирование" используется некоторыми людьми для обсуждения относительной распространенности или отсутствия неявных преобразований.

  • Профессионалы не могут согласиться с тем, что означают термины.

  • В целом вы вряд ли будете информировать или просвещать свою аудиторию.

Печальная истина заключается в том, что когда дело доходит до систем типов, "сильные" и "слабые" не имеют общепринятого технического смысла. Если вы хотите обсудить относительную силу типа систем лучше обсуждать, какие именно гарантии и не предоставляются. Например, можно задать хороший вопрос: "Кажется ли каждое значение определенного типа (или класса) созданным путем вызова одного из конструкторов этого типа?" В C ответ - нет. В CLU, F # и Haskell это да. Для С++ я не уверен, мне хотелось бы знать.

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

Означает ли это другое?

На педантическом уровне нет, потому что слово "сильный" на самом деле ничего не значит. Но на практике люди почти всегда делают одно из двух:

  • Они (неправильно) используют "сильные" и "слабые" для обозначения "статические" и "динамические", и в этом случае они (неправильно) используют "сильно типизированные" и "статически типизированные" взаимозаменяемые.

  • Они используют "сильные" и "слабые" для сравнения свойств систем статического типа. Очень редко слышать, как кто-то говорит о "сильной" или "слабой" динамической системе. За исключением FORTH, у которого на самом деле нет какой-либо системы типов, я не могу придумать динамически типизированный язык, в котором система типов может быть искажена. Сортировка по определению, эти проверки являются пугающими в механизм выполнения, и каждая операция проверяется на предмет здравого смысла перед выполнением.

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

Ответ 2

Это часто неправильно понимают, поэтому позвольте мне прояснить это.

Статический/динамический ввод

Статическая типизация - это тип, связанный с переменной. Типы проверяются во время компиляции.

Динамическая типизация - это тип привязки к значению. Типы проверяются во время выполнения.

Итак, в Java, например:

String s = "abcd";

s будет "навсегда" be String. В течение своей жизни он может указывать на разные String (так как s является ссылкой в ​​Java). Он может иметь значение null, но он никогда не будет ссылаться на Integer или List. Эта статическая типизация.

В PHP:

$s = "abcd";          // $s is a string
$s = 123;             // $s is now an integer
$s = array(1, 2, 3);  // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class

Эта динамическая типизация.

Сильный/слабый ввод

(Изменить предупреждение!)

Сильная типизация - это фраза, не имеющая широко согласованного значения. Большинство программистов, которые используют этот термин для обозначения чего-то другого, кроме статического ввода, используют его, чтобы подразумевать, что существует дисциплина типа, которая применяется компилятором. Например, CLU имеет сильную систему типов, которая не позволяет клиентскому коду создавать значение абстрактного типа, за исключением использования конструкторов, предоставляемых типом. C имеет несколько сильную систему типов, но ее можно "подорвать" до степени, потому что программа всегда может отличать значение одного типа указателя до значения другого типа указателя. Так, например, в C вы можете взять значение, возвращаемое malloc(), и весело применить его к FILE*, и компилятор не попытается остановить вас, или даже предупредит вас, что вы делаете что-то хитрое.

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

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

Оригинал этого ответа сочетал слабую типизацию с неявным преобразованием (иногда также называемым "неявным продвижением" ). Например, в Java:

String s = "abc" + 123; // "abc123";

Этот код является примером неявной рекламы: 123 неявно преобразуется в строку перед объединением с "abc". Можно утверждать, что компилятор Java перезаписывает этот код как:

String s = "abc" + new Integer(123).toString();

Рассмотрим классический PHP-вопрос "начинается с":

if (strpos('abcdef', 'abc') == false) {
  // not found
}

Ошибка здесь в том, что strpos() возвращает индекс соответствия, равный 0. 0 принуждается к boolean false, и, таким образом, условие действительно истинно. Решение заключается в использовании === вместо ==, чтобы избежать неявного преобразования.

В этом примере показано, как комбинация неявного преобразования и динамического ввода может сбить программистов.

Сравните это с Ruby:

val = "abc" + 123

который является ошибкой во время выполнения, поскольку в Ruby объект 123 не неявно преобразован только потому, что он передается методу +. В Ruby программист должен сделать явное преобразование:

val = "abc" + 123.to_s

Сравнение PHP и Ruby - хорошая иллюстрация. Оба являются динамически типизированными языками, но PHP имеет множество неявных преобразований и Ruby (возможно, удивительно, если вы незнакомы с ним).

Статический/динамический против сильного/слабого

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

Итак, чтобы ответить на ваш вопрос: еще один способ взглянуть на это, в основном правильное - сказать, что статическая типизация - это безопасность типа времени компиляции, а сильная типизация - это безопасность типа времени выполнения.

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

Но важно понимать, что язык может быть статическим/сильным, статическим/слабым, динамическим/сильным или динамическим/слабым.

Ответ 3

Сильно напечатанное означает, что существуют ограничения между преобразованиями между типами. Статически типизированное означает, что типы не являются динамическими - вы не можете изменить тип переменной после ее создания.

Ответ 4

Приведение данных не обязательно означает слабо типизированное, потому что иногда его синтаксический сахар:

Пример выше Java, который слабо типизирован из-за

String s = "abc" + 123;

Не слишком типизированный пример, потому что он действительно делает:

String s = "abc" + new Integer(123).toString()

При построении нового объекта также принудительно вводится некорректное наложение данных. Java - очень плохой пример слабо типизированного (и любой язык, который имеет хорошее отражение, скорее всего, не будет слабо типизирован). Поскольку время выполнения языка всегда знает, что такое тип (исключением могут быть родные типы).

Это не похоже на C. C - один из лучших примеров слабо типизированного. Время выполнения не имеет понятия, если 4 байта является целым числом, структурой, указателем или 4 символами.

Время выполнения языка действительно определяет, имеет ли его слабое впечатывание иначе его действительно справедливое мнение.

EDIT: После того, как мы подумали об этом, это не обязательно так, поскольку во время выполнения не требуется, чтобы все типы, используемые в системе времени выполнения, были строго типизированной системой. Haskell и ML имеют такой полный статический анализ, что они могут потенциально исключать информацию о типе из среды выполнения.

Ответ 5

Оба являются полюсами на двух разных осях:

  • строго типизированный или слабо типизированный
  • статически типизированный или динамически типизированный

Сильно введенный означает, что a не будет автоматически преобразовываться из одного типа в другой. Слабо набранное - это противоположное: Perl может использовать строку типа "123" в числовом контексте, автоматически преобразуя ее в int 123. Сильно типизированный язык, такой как python, не будет делать этого.

Статически типизированный означает, что компилятор определяет тип каждой переменной во время компиляции. Динамически типизированные языки определяют только типы переменных во время выполнения.

Ответ 6

Сильная типизация, вероятно, означает, что переменные имеют четко определенный тип и что существуют строгие правила объединения переменных разных типов в выражения. Например, если A является целым числом, а B является float, то строгим правилом относительно A + B может быть то, что A передается в float, а результат возвращается как float. Если A - целое число, а B - строка, то строгим правилом может быть то, что A + B недействителен.

Статическая типизация, вероятно, означает, что типы назначаются во время компиляции (или ее эквивалент для некомпилированных языков) и не могут меняться во время выполнения программы.

Обратите внимание, что эти классификации не являются взаимоисключающими, и я бы ожидал, что они будут встречаться часто. Многие сильно типизированные языки также статически типизированы.

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

Ответ 7

Один не означает другого. Для ввода текста статически это означает, что типы всех переменных известны или выводятся во время компиляции.

A сильно типизированный язык не позволяет вам использовать один тип как другой. C - слабо типизированный язык и является хорошим примером того, что сильно типизированные языки не позволяют. В C вы можете передать элемент данных неправильного типа, и он не будет жаловаться. На сильно типизированных языках вы не можете.

Ответ 8

В компьютерном программировании языки программирования часто разговорно называются строго типизированными или слабо типизированными. Эти термины не имеют точного определения, но, как правило, строго типизированный язык с большей вероятностью генерирует ошибку или отказывается компилировать, если аргумент, переданный функции, не соответствует ожидаемому типу. С другой стороны, очень слабо типизированный язык может давать непредсказуемые результаты или может выполнять неявное преобразование типов