Pour comprendre cette affirmation, nous devons d'abord comprendre ce qu'un système de type statique nous achète. En substance, ce qu'un système de type statique nous donne est une garantie: si les vérifications de type de programme, une certaine classe de comportements d'exécution ne peut pas se produire.
Cela semble inquiétant. Eh bien, un vérificateur de type est similaire à un vérificateur de théorème. (En fait, selon l'isomorphisme de Curry-Howard, c'est la même chose.) Une chose qui est très particulière à propos des théorèmes est que lorsque vous prouvez un théorème, vous prouvez exactement ce que dit le théorème, pas plus. (C'est par exemple pourquoi, lorsque quelqu'un dit "J'ai prouvé que ce programme est correct", vous devez toujours demander "veuillez définir" correct "".) La même chose est vraie pour les systèmes de type. Lorsque nous disons "un programme est sûr pour le type", nous ne voulons pas dire qu'aucune erreur possible ne peut se produire. Nous pouvons seulement dire que les erreurs que le système de type nous promet d'éviter ne peuvent pas se produire.
Ainsi, les programmes peuvent avoir une infinité de comportements d'exécution différents. Parmi ceux-ci, un nombre infini de ceux-ci sont utiles, mais aussi un nombre infini de ceux-ci sont "incorrects" (pour diverses définitions de "l'exactitude"). Un système de type statique nous permet de prouver qu'un certain ensemble fini et fixe de ces infiniment de comportements d'exécution incorrects ne peut pas se produire.
La différence entre les différents types de systèmes réside essentiellement dans le fait de savoir combien, et combien de comportements d'exécution complexes ils peuvent ne pas se produire. Les systèmes de type faible tels que Java ne peuvent prouver que des choses très basiques. Par exemple, Java peut prouver qu'une méthode qui est typée comme retournant un String
ne peut pas retourner un List
. Mais, par exemple, il ne peut pas prouver que la méthode ne reviendra pas. Il ne peut pas non plus prouver que la méthode ne lèvera pas d'exception. Et il ne peut pas prouver qu'il ne renverra pas le mauvais String
- tout String
satisfera le vérificateur de type. (Et, bien sûr, même null
satisfera aussi bien.) Il y a même des choses que Java ne peut pas prouver très simple, ce qui est la raison pour laquelle nous avons des exceptions comme ArrayStoreException
, ClassCastException
ou tout le monde le favori, le NullPointerException
.
Des systèmes de types plus puissants comme Agda peuvent également prouver des choses comme «renverra la somme des deux arguments» ou «renvoie la version triée de la liste passée en argument».
Maintenant, ce que les concepteurs d'Elm entendent par la déclaration selon laquelle ils n'ont pas d'exceptions d'exécution, c'est que le système de type d'Elm peut prouver l'absence de (une partie importante) des comportements d'exécution qui, dans d'autres langues, ne peuvent pas être prouvés comme ne se produisant pas et pourraient donc conduire à un comportement erroné lors de l'exécution (ce qui dans le meilleur des cas signifie une exception, dans le pire des cas, un crash, et dans le pire des cas, aucun crash, aucune exception, et juste un résultat silencieusement erroné).
Donc, ils ne disent pas "nous n'implémentons pas d'exceptions". Ils disent que "les choses qui seraient des exceptions d'exécution dans des langages typiques que les programmeurs typiques venant avec Elm auraient expérimentés, sont prises par le système de type". Bien sûr, quelqu'un venant d'Idris, Agda, Guru, Epigram, Isabelle / HOL, Coq ou d'autres langues similaires verra Elm comme assez faible en comparaison. L'instruction s'adresse davantage aux programmeurs Java, C♯, C ++, Objective-C, PHP, ECMAScript, Python, Ruby, Perl,… typiques.