Системы типов: номинальные и структурные, явные и неявные.


24

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

Из того, что я понимаю:

  • Номинал: Совместимость типов основана на имени типа.
  • Структурный: Совместимость типов основана на структуре типов, например, в C, если 2 переменные являются типами структур с разными именами, но с одинаковой структурой, их типы совместимы.

Теперь о явном и неявном: почему он отличается от статической и динамической типизации? В статической типизации типы будут явными, в то время как в динамической типизации типы являются неявными. Я прав?

Ответы:


29

В динамически типизированной системе значения имеют типы во время выполнения, а переменные и функции - нет. В статически типизированной системе переменные и функции имеют типы, известные и проверенные во время компиляции. Например, в Python xможет быть что угодно ; во время выполнения, если это 1число, а если это - "foo"строка. Вы бы знали только, какой тип xбыл во время выполнения, и он может отличаться при каждом запуске программы. На таком языке, как Java, вы написали int xбы, если xбы это было число, и знали бы, что во время компиляции это xвсегда должно быть int.

«Явный» и «неявный» типы относятся к системам статических типов. Определяющей характеристикой статической системы является то, что типы известны во время компиляции, но не обязательно, что они должны быть записаны. В Java типы являются явными - вы должны записать их. Поэтому в Java метод может выглядеть примерно так:

public int foo(String bar, Object baz) { ... }

Типы известны как во время компиляции (статические), так и записаны (явные). Однако есть также языки, которые не заставляют вас писать тип. Они могут определить тип функции по ее телу и то, как она используется. Примером может служить OCaml, где вы можете написать что-то вроде:

let foo x = x + 1

Так как вы использовали +, OCaml может выяснить, что xдолжно быть intвсе самостоятельно. Таким образом, тип foo( foo : int -> int) будет известно во время компиляции, так же , как , например Java. Это полностью статично. Однако, поскольку компилятор может самостоятельно определять, какими должны быть типы, вам не нужно их самим писать: они неявные.

Короче говоря, является ли система типов явной или неявной, это свойство статических систем. Это совершенно другой вопрос по сравнению с тем, является ли система типов динамической или статической.

Часто у вас есть системы типов, которые иногда являются явными, а иногда и неявными.

Например, я считаю, что C # позволяет вывести типы, используя varключевое слово. Поэтому вместо того, чтобы писать int x = 10, вы можете написать, var x = 10и компилятор выяснит, что xэто должно быть int. C ++ делает нечто подобное с auto. Эти системы обычно являются явными, но имеют некоторый вывод.

С другой стороны, существуют системы, которые обычно неявны, но иногда вынуждают вас выписывать сигнатуру типа. Haskell - отличный пример. В большинстве случаев Haskell может определить типы для вас. Однако иногда вы можете написать код, который неоднозначен, например show . read, когда Haskell не может самостоятельно определить типы. В этом случае вы будете вынуждены явно указать тип либо showили read. Кроме того, некоторые более продвинутые возможности системы типов (такие как полиморфизм ранга n) делают вывод неразрешимым, то есть он не гарантированно останавливается. Это означает, что код, использующий эту функцию, часто нуждается в явных сигнатурах типов.


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

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

Хороший ответ, но это не относится к номинальной или структурной типизации. Редактирование было бы здорово.
lunchmeat317

7
  • static vs dynamic описывает, когда проверяются типы (более или менее во время компиляции или во время выполнения)

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

(И есть варианты, наиболее известным является вариант структурной типизации, который рассматривает только то, что используется вместо всего типа, известного как типирование утки).

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

Например, системы типов C ++ являются статическими, в основном номинальными, но структурными, когда вы рассматриваете шаблоны (и вы можете рассматривать часть проблем, связанных с концепциями в C ++, как конфликт между теми, кто хочет от утиной типизации до полной формы структурной типизации и желающим перейти на именную печать). А использование классов и наследования позволяет использовать динамическую и именную типизацию в некоторых случаях.

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


1

Структурный: Совместимость типов основана на структуре типов, например, в C, если 2 переменные являются типами структур с разными именами, но с одинаковой структурой, их типы совместимы.

Обычно это не тот случай. Структурная типизация означает, что Bэто подтип, Aесли он может удовлетворить Aинтерфейс. Обычно это означает наличие членов с одинаковым именем; не просто та же структура в памяти.

Это отличается от номинативной типизации, которая требует указания супертипов при объявлении.


1

Наилучшее объяснение различий между (на самом деле, подчинением) динамических и статических систем типов в этом сообщении в блоге Боба Харпера:

Его основной смысл можно сформулировать так:

  • динамические языки - это статические языки только одного типа

1
Ссылки могут испортиться; Вы должны процитировать наиболее релевантные фрагменты статьи, чтобы они сохранились для потомков, даже если блог пойдет не так.
Довал

2
Конечно. Я думаю, что в этом случае добавленного мною предложения достаточно :)
Эдуардо Пареджа Тобес
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.