Per comprendere questa affermazione, dobbiamo prima capire cosa ci compra un sistema di tipo statico. In sostanza, ciò che ci offre un sistema di tipo statico è una garanzia: se il tipo di programma verifica, una determinata classe di comportamenti di runtime non può verificarsi.
Sembra inquietante. Bene, un controllo di tipo è simile a un controllo di teorema. (In realtà, secondo il Curry-Howard-Isomorfismo, sono la stessa cosa.) Una cosa che è molto peculiare dei teoremi è che quando dimostrate un teorema, dimostrate esattamente ciò che dice il teorema, non di più. (Questo è ad esempio il motivo per cui, quando qualcuno dice "Ho dimostrato che questo programma è corretto", dovresti sempre chiedere "per favore, definisci" corretto ".) Lo stesso vale per i sistemi di tipi. Quando diciamo "un programma è sicuro per i tipi", ciò che intendiamo non è che non possa verificarsi alcun errore. Possiamo solo dire che gli errori che il sistema di tipi ci promette di prevenire non possono verificarsi.
Quindi, i programmi possono avere infiniti comportamenti di runtime infiniti. Di questi, infinitamente molti sono utili, ma anche infinitamente molti sono "errati" (per varie definizioni di "correttezza"). Un sistema di tipo statico ci consente di dimostrare che non può verificarsi un certo insieme finito finito di quegli infiniti comportamenti di runtime errati.
La differenza tra i diversi sistemi di tipi sta fondamentalmente in quali, quanti e comportamenti di runtime complessi possono dimostrare di non verificarsi. I sistemi di tipo debole come Java possono solo dimostrare cose molto basilari. Ad esempio, Java può dimostrare che un metodo che viene digitato come String
return a non può restituire a List
. Ma, per esempio, può non dimostrare che il metodo non non tornare. Inoltre, non può dimostrare che il metodo non genererà un'eccezione. E non può provare che non restituirà il torto String
- nessuno String
soddisferà il controllo del tipo. (E, naturalmente, anche null
in grado di soddisfare pure.) Ci sono anche cose molto semplici che Java non può provare, ed è per questo che abbiamo eccezioni come ArrayStoreException
, ClassCastException
o ognuno di preferito, il NullPointerException
.
Sistemi di tipo più potenti come quelli di Agda possono anche dimostrare cose come "restituirà la somma dei due argomenti" o "restituisce la versione ordinata della lista passata come argomento".
Ora, ciò che i progettisti di Elm intendono con l'affermazione che non hanno eccezioni di runtime è che il sistema di tipi di Elm può dimostrare l'assenza di (una parte significativa di) comportamenti di runtime che in altre lingue non possono essere dimostrati non si verificano e quindi potrebbero condurre a un comportamento errato in fase di esecuzione (che nel migliore dei casi significa un'eccezione, nel peggiore dei casi significa un arresto anomalo e, nel peggiore dei casi, nessun arresto anomalo, nessuna eccezione e solo un risultato silenziosamente sbagliato).
Quindi, essi sono non dicendo "non si procede eccezioni". Stanno dicendo "cose che sarebbero eccezioni di runtime in linguaggi tipici con cui i programmatori tipici che arrivano a Elm avrebbero esperienza, sono catturati dal sistema di tipi". Ovviamente, qualcuno che viene da Idris, Agda, Guru, Epigram, Isabelle / HOL, Coq o lingue simili vedrà Elm come piuttosto debole in confronto. L'affermazione è più rivolta ai programmatori Java, C♯, C ++, Objective-C, PHP, ECMAScript, Python, Ruby, Perl, ....