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.