Para entender esta afirmación, primero debemos entender qué nos compra un sistema de tipo estático. En esencia, lo que nos ofrece un sistema de tipo estático es una garantía: iff el tipo de programa verifica, no puede ocurrir una cierta clase de comportamientos de tiempo de ejecución.
Eso suena ominoso. Bueno, un verificador de tipos es similar a un verificador de teoremas. (En realidad, según el Curry-Howard-Isomorfismo, son lo mismo.) Una cosa que es muy peculiar acerca de los teoremas es que cuando uno prueba un teorema, prueba exactamente lo que dice el teorema, nada más. (Eso es, por ejemplo, por qué, cuando alguien dice "He comprobado que este programa es correcto", siempre debe preguntar "defina 'correcto'".) Lo mismo es cierto para los sistemas tipográficos. Cuando decimos "un programa es de tipo seguro", lo que queremos decir es no que no puede ocurrir ningún error posible. Solo podemos decir que los errores que el sistema de tipos nos promete evitar no pueden ocurrir.
Por lo tanto, los programas pueden tener infinitos comportamientos de ejecución diferentes. De ellos, infinitos son útiles, pero también infinitos son "incorrectos" (para varias definiciones de "corrección"). Un sistema de tipo estático nos permite probar que no se puede producir un determinado conjunto fijo finito de esos infinitos comportamientos incorrectos en tiempo de ejecución.
La diferencia entre los diferentes sistemas de tipos radica básicamente en qué, cuántos y en qué tan complejos comportamientos de tiempo de ejecución se puede demostrar que no ocurren. Los sistemas tipográficos débiles como los de Java solo pueden probar cosas muy básicas. Por ejemplo, Java puede probar que un método que se escribe como devolver un String
no puede devolver un List
. Pero, por ejemplo, puede no demostrar que el método no regresará. Tampoco puede probar que el método no arrojará una excepción. Y no puede probar que no devolverá el error String
; cualquier String
satisfará el comprobador de tipos. (Y, por supuesto, incluso null
también lo satisfará.) Incluso hay cosas muy simples que Java no puede probar, por lo que tenemos excepciones como ArrayStoreException
, ClassCastException
, o el favorito de todos, el NullPointerException
.
Los sistemas tipográficos más potentes, como el de Agda, también pueden probar cosas como "devolverá la suma de los dos argumentos" o "devuelve la versión ordenada de la lista pasada como un argumento".
Ahora, lo que los diseñadores de Elm quieren decir con la afirmación de que no tienen excepciones de tiempo de ejecución es que el sistema de tipos de Elm puede probar la ausencia de (una parte significativa de) los comportamientos de tiempo de ejecución que en otros idiomas no pueden ni se ha comprobado que no se produce y, por lo tanto, puede dar lugar a un comportamiento erróneo en el tiempo de ejecución (lo que en el mejor de los casos significa una excepción, en el peor de los casos significa un fallo y, en el peor de los casos, no hay bloqueo, no hay excepción y solo resultado incorrectamente silencioso).
Entonces, ellos no dicen "no implementamos excepciones". Dicen que "las cosas que serían excepciones en tiempo de ejecución en los lenguajes típicos con los que los programadores típicos que vienen a Elm tendrían experiencia, están atrapadas por el sistema de tipos". Por supuesto, alguien que venga de Idris, Agda, Guru, Epigram, Isabelle / HOL, Coq o idiomas similares verá a Elm como un débil débil en comparación. La declaración está más dirigida a los programadores típicos de Java, C♯, C ++, Objective-C, PHP, ECMAScript, Python, Ruby, Perl, ...