Чтобы понять это утверждение, мы сначала должны понять, что нам покупает статическая система типов. По сути, то, что дает нам статическая система типов, является гарантией: если программа проверяет тип, определенный класс поведения во время выполнения не может возникнуть.
Это звучит зловеще. Что ж, проверка типов похожа на проверку теорем. (На самом деле, согласно Каром-Говарду-Изоморфизму, это одно и то же.) Одна вещь, которая очень специфична в теоремах, это то, что когда вы доказываете теорему, вы доказываете в точности то, что говорит теорема, не более. (Вот, например, почему, когда кто-то говорит «Я доказал, что эта программа верна», вы всегда должны спрашивать «пожалуйста, определите« правильно »».) То же самое верно для систем типов. Когда мы говорим «программа является типобезопасной», мы имеем в виду не то, что возможная ошибка не возникает. Мы можем только сказать, что ошибки, которые система типов обещает нам предотвратить, не могут возникнуть.
Таким образом, программы могут иметь бесконечно много разных поведений во время выполнения. Из них бесконечно много полезных, но также бесконечно много «неправильных» (для разных определений «правильности»). Система статических типов позволяет нам доказать, что определенный конечный фиксированный набор этих бесконечно многих некорректных поведений во время выполнения не может возникнуть.
Разница между системами разных типов заключается в том, что, сколько и как сложно они могут возникнуть во время выполнения. Слабые системы типов, такие как Java, могут доказать только самые простые вещи. Например, Java может доказать, что метод, типизированный как возвращающий a, String
не может вернуть a List
. Но, например, он не может доказать, что метод не вернется. Это также не может доказать, что метод не будет генерировать исключение. И он не может доказать, что он не вернет неправильное String
- любой String
удовлетворит проверку типов. (И, конечно, даже null
удовлетворит его.) Есть даже очень простые вещи , которые Java не могут доказать, что именно поэтому у нас есть исключения , например ArrayStoreException
, ClassCastException
или все любимец, то NullPointerException
.
Более мощные системы типов, такие как Agda, могут также доказать, что «вернет сумму двух аргументов» или «вернет отсортированную версию списка, переданного в качестве аргумента».
Теперь, что дизайнеры Elm подразумевают под утверждением, что у них нет исключений во время выполнения, так это то, что система типов Elm может доказать отсутствие (значительную часть) поведения во время выполнения, которое в других языках не может быть доказано, что оно не возникает и, следовательно, может привести к к ошибочному поведению во время выполнения (что в лучшем случае означает исключение, в худшем случае означает сбой, а в худшем случае все означает отсутствие сбоя, исключение и просто неверный результат).
Таким образом, они не говорят «мы не реализуем исключения». Они говорят, что «вещи, которые могли бы быть исключениями времени выполнения в типичных языках, с которыми обычные программисты, приходящие в Elm, имели бы опыт, попадают в систему типов». Конечно, кто-то из Идриса, Агды, Гуру, Эпиграма, Изабель / HOL, Coq или похожих языков увидит Элма довольно слабым по сравнению. Это утверждение больше предназначено для типичных программистов на Java, C♯, C ++, Objective-C, PHP, ECMAScript, Python, Ruby, Perl,….