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


24

Я трохи заплутаний у різниці між системами номінального та структурного типу. Може хтось пояснить, чим вони відрізняються?

З того, що я розумію:

  • Номінальна: сумісність типу заснована на назві типу.
  • Структурна: сумісність типів заснована на структурі типів, наприклад, у випадку C, якщо 2 змінні - це структури структури з різними іменами, але однакові структури, то їх типи сумісні.

Тепер про явне та неявне: чому він відрізняється від статичного та динамічного введення тексту? При статичному введенні типи будуть явними, а при динамічному введенні - типи неявними. Чи правий я?

Відповіді:


29

У динамічно типізованій системі значення мають типи під час виконання, але змінних та функцій немає. У статично типізованій системі змінні та функції мають типи, відомі та перевірені під час компіляції. Напр. В Python xможе бути будь-що ; під час виконання, якщо це 1число, а якщо воно є "foo"- це рядок. Ви знаєте лише, який тип xбув під час виконання, і він міг бути різним щоразу, коли ви запускали програму. На такій мові, як Java, ви писали б, int xякби xце було число, і ви знали б у час компіляції, що xзавжди має бути an 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
Насправді, є кілька мов, з якими можна назвати явний динамічний набір тексту . Зазвичай ці мови дозволяють коментувати вирази за допомогою типів, і тоді ці типи будуть перевірятися під час виконання відповідно до типу виконання виразу.
Jörg W Mittag

просто точність: системи типів не явні чи явні. Мова йде лише про умовивід типу, який по суті є способом генерування дійсних термінів у системі типів з іншого (іноді не визначеного) синтаксису.
Едуардо Пареджа Тобес

Хороша відповідь, але це не стосується номінальної та структурної типізації. Редагування було б чудово.
обідне м'ясо317

7
  • статичний vs динамічний описує, коли типи перевіряються (більше або менше під час компіляції або під час виконання)

  • номінальний vs структурний описує, коли два типи вважаються однаковими.

(І є варіанти. Найвідомішим є варіант структурного набору тексту, який розглядає лише те, що використовується замість всього типу, відомого як типінг качки).

Можливі чотири комбінації (статична номінальна, статична структурна, динамічна номінальна, динамічна структурна), і мови досить часто не суто в одному класі, але мають аспекти, які є в інших.

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

Мова, що в системах динамічного типу часто використовують структурний набір тексту, але CLOS як номінальний аспект.


1

Структурна: сумісність типів заснована на структурі типів, наприклад, у випадку C, якщо 2 змінні - це структури структури з різними іменами, але однакові структури, то їх типи сумісні.

Зазвичай це не так. Структурне введення означає, що Bце підтип, Aякщо він може задовольнити Aінтерфейс. Зазвичай це означає мати членів з однаковою назвою; не просто однакова структура в пам'яті.

Це відрізняється від номінативного набору тексту, який вимагає, щоб у декларації були вказані супертипи.


1

Найкраще пояснення, яке я бачив, на відміну від (насправді підзарядки) систем динамічного та статичного типу, - у цьому дописі Боб Харпер:

Його основний момент можна було б узагальнити як:

  • динамічні мови - це статичні мови, що мають лише один тип

1
Посилання можуть піти погано; ви повинні навести найрелевантніші статті статті, щоб вони збереглися для нащадків, навіть якщо блог виходить на капут.
Доваль

2
Звичайно. Я думаю, що в цьому випадку пропозицію, яке я додав, достатньо :)
Едуардо Пареджа Тобес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.