Чем компиляция elm отличается от проверенных исключений Java?

Заявление elm об нулевом времени выполнения-исключений является одним из о его основных преимуществах (см. официальный сайт),

Но если вы перестанете думать об этом, ничто не помешает вам поделить на ноль или исчерпать память.

Что в основном делает компилятор elm, так это заставляет вас покрывать все возможные пути, которые могут привести к исключению.

Например:

import String exposing (toInt)
toIntOrZero s = case toInt s of
                          Err e -> 0
                          Ok val -> val

Но чем это отличается от печально известной функции "checked-exceptions" в java ?

public static Integer toIntOrZero(String s) {
    try { return Integer.valueOf(s); }
    catch (NumberFormatException e) { return 0; }
}

Я никогда не слышал никаких заявлений о том, что java является языком с нулевым временем выполнения.


person Uri Goren    schedule 17.10.2017    source источник
comment
Однако в Java все еще есть непроверенные исключения. В лучшем случае вы можете заявить, что у Java есть возможность быть языком с нулевым временем выполнения.   -  person Carcigenicate    schedule 18.10.2017
comment
Справедливое замечание, так что вся суета в elm связана с функцией проверенных исключений, которую программисты ненавидят, а Microsoft решила не включать в c# ?   -  person Uri Goren    schedule 18.10.2017
comment
Не могу сказать. Не знаю Elm, и прошло слишком много времени с тех пор, как я использовал Java, чтобы комментировать его. Просто увидел логическую ошибку. Извиняюсь.   -  person Carcigenicate    schedule 18.10.2017
comment
«Программисты ненавидят»? Я не.   -  person user207421    schedule 18.10.2017
comment
Вы плохо читаете статью. В статье говорится, что Elm утверждает, что у него нет исключений во время выполнения. Ричард Фельдман говорит, что их производственная система работает уже 2 года без каких-либо исключений во время выполнения, в основном благодаря тому, что язык устраняет наиболее распространенную причину исключений во время выполнения. Если убрать значение null и оператор throw, останется совсем немного, чтобы вызвать исключение. Это не означает, что код не содержит ошибок, просто он не будет генерировать исключения во время выполнения.   -  person Andreas    schedule 18.10.2017
comment
Я никогда не слышал заявлений о том, что java — язык с нулевыми исключениями во время выполнения Конечно, нет, потому что это не так. Вы также не слышали никаких заявлений о том, что java — это школьный автобус.   -  person Andreas    schedule 18.10.2017
comment
претензия Elm заключается в следующем: одна из гарантий Elm заключается в том, что вы не увидите ошибки времени выполнения на практике. Они не претендуют на нулевые исключения времени выполнения». Вопрос отклонен как бесполезный, поскольку он основан на неправильном прочтении статьи.   -  person Andreas    schedule 18.10.2017
comment
@Андреас, это не неправильное прочтение, посмотри это интервью с создателем вяза Эваном Чаплицким. changelog.com/podcast/218. Это короткая цитата: По сути, мы поняли, что вы можете просто сказать: «Эти программы не получают ошибок во время выполнения». Это краткое изложение всей теории, над которой люди работали десятилетиями. Итак, мы взяли эту основную идею, и это всего лишь часть Elm.   -  person Uri Goren    schedule 18.10.2017
comment
@UriGoren Ваш вопрос касается языков с нулевым временем выполнения. Элм не претендует на это. Они используют фразы вроде «по существу» и «на практике» для обозначения «близок к нулю». Ваш вопрос начинается с утверждения elm о нулевых исключениях во время выполнения, и это неверно, поскольку на самом деле они не утверждают, что имеют нулевые исключения во время выполнения.   -  person Andreas    schedule 19.10.2017
comment
На официальном веб-сайте elm (elm-lang.org) жирным шрифтом на первой странице написано Нет исключений во время выполнения.   -  person Uri Goren    schedule 19.10.2017
comment
Мой вопрос в том, если это так, то это только из-за повторного изобретения checked-exception?   -  person Uri Goren    schedule 19.10.2017
comment
В elm repl 1 / 0 дает Infinity : Float, а не исключение.   -  person Matt McHenry    schedule 21.10.2017
comment
@Ури Горен, привет. Ваш пример слишком надуманный (надеюсь). Вы когда-нибудь задумывались об объединении кода ошибки с результатом правильного ввода 0 ? Юк. Это показывает IMO проблему с исключениями: они образуют отдельный путь возврата из вашего стека вызовов (стек исключений). И слишком утомительно правильно обрабатывать исключения. Что создает соблазн реинтеграции обычного стека возврата с помощью такого отвратительного подтверждения, как замена ошибки значением по умолчанию.   -  person Titou    schedule 10.11.2017


Ответы (2)


Пожалуйста, не слишком зацикливайтесь на том, что по сути является маркетинговой гиперболой. Конечно, существуют классы ошибок, которые вы никогда не сможете полностью исключить с помощью любого компилятора.

Таким образом, я всегда относился к заявлениям об отсутствии исключений во время выполнения с долей скептицизма, но думаю, что понимаю намерение сторонника. Elm был создан как альтернатива разработке интерфейсных приложений на Javascript, который представляет собой запутанный мир, где изобилуют исключения, являющиеся лишь частью повседневной жизни. В Elm намного сложнее выстрелить себе в ногу, и без особых усилий, если вы проведете базовое тестирование работоспособности своего приложения, у вас, вероятно, никогда не будет исключений во время выполнения в рабочей среде. .

Elm резко снижает вероятность исключений несколькими способами.

  1. В языке нет понятия выбрасываемого исключения, кроме Debug.crash, которое, как следует из его названия, на самом деле должно использоваться только для отладки и заглушки неполных логических путей.

    Поскольку исключаемых исключений не существует, проблемы с обработкой чаще всего решаются с помощью таких типов, как Result и Maybe.

    Это можно рассматривать как аналогию проверенных исключений Java, но концептуально они очень отличаются от меня. Давайте смотреть правде в глаза. Исключениями злоупотребляют. Вы упоминаете пример в Java, где Integer.valueOf() говорит, что он собирается вернуть int, но если вы передадите ему что-то еще, он разворачивает стек и всплывает до тех пор, пока какая-то функция, надеюсь, не поймает его. Мне это кажется очень запутанным, и, конечно, проверенные исключения могут помочь уменьшить окно для распространения сбоя, но основной факт заключается в том, что исключение — это неправильный инструмент для бизнес-логики.

    Альтернативой генерации исключения было бы иметь классы, аналогичные типам Result и Maybe Elm, но это было бы почти невозможно в первые дни Java сделать чисто, и даже с помощью дженериков написание таких типов более утомительно и приводит к ошибкам. склонны, чем простота типов Вяза. И из-за системы закрытого типа Elm,

  2. Неполные совпадения с образцом приводят к сбою компиляции.

    В Java и Javascript нет возможности провести исчерпывающую проверку соответствия шаблону, потому что система типов не позволяет этого. Конечно, Typescript представил некоторые функции, но вы должны согласиться на это. В Elm вы должны явно обрабатывать все случаи. Конечно, я полагаю, вы могли бы возразить, что Elm позволяет вам отказаться от исчерпывающего сопоставления с образцом, заканчивая все операторы case _, но это было бы просто глупым злоупотреблением языком. Эти проверки предназначены для того, чтобы помочь вам, и я чувствую себя намного спокойнее, потому что у меня нет возможности подписаться на проверку ошибок в Elm — она есть по умолчанию!

  3. неизменность

    Неизменяемость позволяет избежать множества потенциальных типов ошибок, слишком много, чтобы вдаваться в них.

  4. Архитектура Elm предлагает четкое разделение между Javascript и Elm.

    Elm компилируется в Javascript, но архитектура Elm предлагает хороший чистый барьер, чтобы держать все неприятные части Javascript подальше от чистого кода, написанного Elm. Любое исключение, которое может произойти в Javascript, должно обрабатываться этим барьером, так что ошибки ввода-вывода всегда будут преобразованы в удобный для Elm тип без исключений.

В конце концов, исключения во время выполнения все еще возможны (пример: следующий помеченный вопрос Elm касался известного исключения во время выполнения, вызванного рекурсивным определением декодера JSON), и я немного съеживаюсь каждый раз, когда слышу, как кто-то говорит, что невозможно получить исключение в вязе. Дело в том, что исключения возможны, но почти все исключения, с которыми вы сталкиваетесь в повседневной разработке Javascript, по существу невозможны в Elm.

person Chad Gilbert    schedule 19.10.2017

Как заметил комментатор, в Java есть непроверенные исключения, поэтому ошибки времени выполнения делают. Elm также имеет непроверяемые исключения для таких вещей, как деление на ноль, но избавляется от наиболее часто встречающихся на практике. И, как упоминается в ответе Чада, типы Elm Maybe/Result на практике работают совершенно иначе, чем проверенные исключения Java. Опытный программист Elm не стал бы писать функцию типа toIntOrZero (а если бы и написал, то, вероятно, не стал бы использовать case ... of, предпочитая вместо этого что-то вроде toIntOrZero = String.toInt >> Result.withDefault 0).

Объединение нескольких операций вместе с Result.map, Result.andThen и т. д. дает очень выразительный способ обработки случаев ошибок, не заставляя программиста слишком углубляться в сорняки. Например, если мы хотим написать функцию, которая проверяет идентификатор, преобразовывая его в Int, ища его в какой-то структуре данных (когда его там может и не быть), а затем проверяя какое-то свойство, связанное с этим пользователем, мы можем написать что-то вроде этого:

lookupUser : Int -> Result String User
lookupUser intId = ...

userInGoodStanding : User -> Bool
userInGoodStanding user = ...

isValidId : String -> Bool
isValidId id = 
  String.toInt id 
  |> Result.andThen lookupUser 
  |> Result.map userInGoodStanding
  |> Result.withDefault False

Это гласит: «Преобразуйте идентификатор в целое число, затем найдите связанного пользователя, затем проверьте пользователя и, если что-то не удалось, верните False». Ваш пробег может варьироваться, но как только вы привыкнете к этому, я (и многие программисты Elm, я думаю!) нахожу это действительно хорошим способом написания кода, устойчивого к ошибкам.

person Alex Lew    schedule 20.10.2017