Sistemi di tipo: nominale contro strutturale, esplicito contro implicito


24

Sono un po 'confuso sulla differenza tra i sistemi di tipo nominale e strutturale. Qualcuno può spiegare in che modo differiscono?

Da quello che ho capito:

  • Nominale: la compatibilità dei tipi si basa sul nome del tipo.
  • Strutturale: la compatibilità dei tipi si basa sulla struttura dei tipi, ad esempio in C se 2 variabili sono tipi di struttura con nomi diversi ma con la stessa struttura, i loro tipi sono compatibili.

Ora su esplicito e implicito: perché è diverso dalla tipizzazione statica e dinamica? Nella tipizzazione statica, i tipi saranno espliciti mentre nella digitazione dinamica, i tipi sono impliciti. Ho ragione?

Risposte:


29

In un sistema tipizzato dinamicamente, i valori hanno tipi in fase di esecuzione ma variabili e funzioni no. In un sistema tipicamente statico, variabili e funzioni hanno tipi conosciuti e controllati in fase di compilazione. Ad esempio in Python xpuò essere qualsiasi cosa ; in fase di esecuzione, se è 1un numero e se lo è "foo", è una stringa. Sapresti solo quale tipo xera in fase di esecuzione e potrebbe essere diverso ogni volta che eseguivi il programma. In una lingua come Java, scriveresti int xse xdovesse essere un numero e sapresti in fase di compilazione che xdeve essere sempre un int.

I tipi "espliciti" e "impliciti" si riferiscono entrambi a sistemi di tipo statico . La caratteristica che definisce un sistema statico è che i tipi sono noti al momento della compilazione, ma non necessariamente che devono essere scritti. In Java, i tipi sono espliciti: devi scriverli. Quindi in Java, un metodo potrebbe assomigliare a:

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

I tipi sono entrambi noti al momento della compilazione (statici) e scritti (espliciti). Tuttavia, ci sono anche lingue che non ti costringono a scrivere il tipo. Possono inferire il tipo di una funzione dal suo corpo e come viene usata. Un esempio potrebbe essere OCaml, dove puoi scrivere qualcosa del tipo:

let foo x = x + 1

Dal momento che hai usato +, OCaml può capire che xdeve essere un inttutto da solo. Quindi il tipo di foo( foo : int -> int) è noto al momento della compilazione, proprio come nell'esempio Java. È completamente statico. Tuttavia, dal momento che il compilatore può capire quali devono essere i tipi da soli, non è necessario scriverli da soli: sono impliciti.

In breve: se un sistema di tipo è esplicito o implicito è una proprietà dei sistemi statici . È una domanda completamente diversa dal fatto che un sistema di tipo sia dinamico o statico.

Spesso hai sistemi di tipi che sono a volte espliciti e talvolta impliciti.

Ad esempio, credo che C # ti permetta di inferire i tipi usando la varparola chiave. Quindi, invece di scrivere int x = 10, puoi scrivere var x = 10e il compilatore scopre che xdeve essere un int. C ++ fa qualcosa di simile con auto. Questi sistemi sono di solito espliciti ma hanno qualche deduzione.

D'altra parte, ci sono sistemi che sono solitamente impliciti ma a volte ti costringono a scrivere una firma di tipo. Haskell è un ottimo esempio. Il più delle volte, Haskell può inferire i tipi per te. Tuttavia, a volte puoi scrivere un codice ambiguo show . read, in cui Haskell non riesce a capire i tipi da solo. In questo caso, saresti costretto a specificare esplicitamente il tipo di uno showo read. Inoltre, alcune caratteristiche più avanzate del sistema di tipi (come il polimorfismo di rango n) rendono l'inferenza indecidibile, cioè non è garantito che si fermi. Ciò significa che il codice che utilizza questa funzione richiede spesso firme di tipo esplicite.


2
In realtà, ci sono alcune lingue con ciò che potresti chiamare la digitazione dinamica esplicita . In genere, tali lingue consentono di annotare espressioni con tipi e quindi tali tipi verranno verificati in fase di esecuzione rispetto al tipo di fase dell'espressione.
Jörg W Mittag,

solo una precisione: i sistemi di tipo non sono impliciti o espliciti. Si tratta solo dell'inferenza di tipo, che è essenzialmente un modo per generare termini validi in un sistema di tipi da una sintassi diversa (a volte non specificata).
Eduardo Pareja Tobes,

Buona risposta, ma questo non riguarda la tipizzazione nominale vs strutturale. Una modifica sarebbe fantastica.
lunchmeat317

7
  • static vs dynamic descrive quando i tipi sono controllati (più o meno in fase di compilazione o in fase di esecuzione)

  • nominale vs strutturale descrive quando due tipi sono considerati uguali.

(E ci sono variazioni, la più nota è la variante della tipizzazione strutturale che considera solo ciò che viene utilizzato al posto dell'intero tipo noto come tipizzazione anatra).

Le quattro combinazioni (nominale statico, statico strutturale, nominale dinamico, strutturale dinamico) sono possibili e le lingue abbastanza spesso non sono puramente in una classe ma hanno aspetti che sono in altre.

Ad esempio, i sistemi di tipi di C ++ sono statici, per lo più nominali ma strutturali quando si considerano i modelli (e si può considerare parte dei problemi relativi ai concetti in C ++ come un conflitto tra coloro che vogliono passare dalla tipizzazione duck a una forma completa di typing strutturale e quelli che vogliono andare alla digitazione nominale). E l'uso di classi ed eredità consente di utilizzare una tipizzazione dinamica e nominale in alcuni casi.

Linguaggio che un sistema di tipo dinamico utilizza spesso la tipizzazione strutturale, ma CLOS come aspetti nominali.


1

Strutturale: la compatibilità dei tipi si basa sulla struttura dei tipi, ad esempio in C se 2 variabili sono tipi di struttura con nomi diversi ma con la stessa struttura, i loro tipi sono compatibili.

Questo di solito non è il caso. La tipizzazione strutturale significa che Bè un sottotipo di Ase può soddisfare Al'interfaccia. Questo di solito significa avere membri con lo stesso nome; non solo la stessa struttura in memoria.

Ciò differisce dalla tipizzazione nominativa che richiede che i super-tipi siano specificati nella dichiarazione.


1

La migliore spiegazione che ho visto sulla distinzione tra (effettivamente la sottosezione di) sistemi di tipo dinamico e statico è in questo post sul blog di Bob Harper:

Il suo punto principale potrebbe essere sintetizzato come:

  • i linguaggi dinamici sono quei linguaggi statici con un solo tipo

1
I collegamenti possono andare male; dovresti citare i pezzi più rilevanti dell'articolo in modo che siano conservati per i posteri anche se il blog diventa kaput.
Doval,

2
Sicuro. Penso che in questo caso la frase che ho aggiunto sia sufficiente :)
Eduardo Pareja Tobes,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.