Sistemi di tipo: nominale vs. strutturale, esplicito vs implicito

23

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

Da quello che capisco:

  • Nominale: la compatibilità del tipo si basa sul nome del tipo.
  • Strutturale: la compatibilità del tipo si basa sulla struttura del tipo, ad es. in C se 2 variabili sono tipi di struct con nomi diversi ma la stessa struttura, quindi 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?

    
posta Noor 01.01.2013 - 11:36
fonte

4 risposte

28

In un sistema digitato in modo dinamico, i valori hanno tipi in fase di esecuzione, ma le variabili e le funzioni no. In un sistema tipizzato staticamente, le variabili e le funzioni hanno tipi conosciuti e controllati in fase di compilazione. Per esempio. in Python x può essere qualsiasi cosa ; in fase di esecuzione, se è 1 è un numero e se è "foo" , è una stringa. Sapresti solo quale tipo x era in fase di runtime e potrebbe essere diverso ogni volta che esegui il programma. In un linguaggio come Java, dovresti scrivere int x se x doveva essere un numero, e sapresti al momento della compilazione che x deve sempre essere un int .

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

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

I tipi sono entrambi noti al momento della compilazione (statico) e scritti (espliciti). Tuttavia, ci sono anche linguaggi che non ti costringono a scrivere il tipo. Possono inferire il tipo di una funzione dal suo corpo e il modo in cui viene utilizzata. Un esempio potrebbe essere OCaml, in cui è possibile scrivere qualcosa come:

let foo x = x + 1

Poiché hai utilizzato + , OCaml può capire che x deve essere un int tutto da solo. Quindi il tipo di foo ( foo : int -> int ) è noto al momento della compilazione, proprio come nell'esempio Java. È completamente statico. Tuttavia, poiché il compilatore può capire da solo quali tipi devono essere, non è necessario scriverli da soli: sono impliciti.

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

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

Ad esempio, credo che C # ti consente di dedurre i tipi utilizzando la parola chiave var . Quindi, invece di scrivere int x = 10 , puoi scrivere var x = 10 e il compilatore capisce che x deve essere un int . C ++ fa qualcosa di simile con auto . Questi sistemi sono solitamente espliciti ma hanno qualche inferenza.

Sul rovescio della medaglia, ci sono sistemi che sono solitamente impliciti, ma a volte ti costringono a scrivere una firma di tipo. Haskell è un grande esempio. La maggior parte delle volte, Haskell può dedurre i tipi per te. Tuttavia, a volte è possibile scrivere codice ambiguo come show . read , in cui Haskell non riesce a capire da solo i tipi. In questo caso, dovresti specificare esplicitamente il tipo di show o read . Inoltre, alcune caratteristiche più avanzate del sistema di tipi (come il polimorfismo di rank-n) rendono l'inferenza indecidibile - cioè, non è garantito l'arresto. Ciò significa che il codice che utilizza questa funzione spesso richiede firme di tipo esplicito.

    
risposta data 01.01.2013 - 13:27
fonte
7
  • statico vs dinamico descrive quando i tipi sono controllati (più o meno al momento della compilazione o al momento dell'esecuzione)

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

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

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

Per esempio, i sistemi di tipi di C ++ sono statici, per lo più nominali ma strutturali se si considerano i modelli (e si può considerare parte dei problemi relativi ai concetti in C ++ come conflitto tra coloro che desiderano digitarli in una forma completa di tipizzazione strutturale e quelli che vogliono andare alla digitazione nominale). E l'uso delle classi e dell'ereditarietà consente in alcuni casi di utilizzare una digitazione dinamica e nominale.

Linguaggio che i sistemi di tipo dinamico usano spesso tipizzazione strutturale, ma CLOS come aspetti nominali.

    
risposta data 01.01.2013 - 13:59
fonte
1

Structural: Type compatibility is based on the type structure, e.g. in C if 2 variables are struct types with different names but the same structure, then their types are compatible.

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

Questo differisce dalla digitazione nominativa che richiede che vengano specificati super-tipi nella dichiarazione.

    
risposta data 01.01.2013 - 16:52
fonte
1

La migliore spiegazione che ho visto della distinzione tra (in realtà la sussunzione di) sistemi di tipo dinamici e statici è in questo post di Bob Harper:

Il suo punto principale potrebbe essere riassunto come:

  • le lingue dinamiche sono quelle lingue statiche con un solo tipo
risposta data 22.05.2014 - 20:49
fonte

Leggi altre domande sui tag