А вот интересно, что с монадами бывает в подобных случаях? В смысле, вызвали какую-то функцию с таким-то параметром, а она не знает, что с ним делать. Или, наоборот, вернула что-то, чего вызывающий не ожидает. Каков будет результат?
Рассказать по существу, что не получилось. В случае NPE - заворачивать в какой-нибудь тип; NPE вообще не должно существовать в природе.
Во втором случае само сообщение абсурдно. Хотя спасибо, что написали because. Но тут же мы как бы имеем дело с контролем версий - ну так и ведите себя реалистично; мерж, может быть, какой-нибудь. Глупо же удивляться неожиданностям и валить все это на юзера.
Ну NPE - это и есть "что-то не получилось". Рассказать по существу можно, если мы заранее позаботились проверить, получилось или нет. А если нет? Т.е., скажем, мы имеем метод, который, не знаю, нам число пи считает. И там внутри у него почему-то сломался думатель. И мы, допустим, по-умному сказали - пусть вернёт не Number, а Option какой-нибудь. И вот он вернул None. Мы в этом случае что будет сделать? Напишем - "не могу продолжать - мне не дают число пи, а дают None". А почему не дают? Неизвестно. Т.е. практически мы делаем немногим большее, чем делает бектрейс. А как сделать больше?
Т.е. либо надо каждую функцию оснастить специальной рассказывалкой (что в общем случае невозможно - есть же библиотеки), либо в конце концов будут всё равно случаи вида "что-то не так, а что - неизвестно, вот вам бектрейс".
None особой пользы не приносит в данном случае; она только показывать может, что это, давай ошибку обрабатывай. Лучше что-то более детальное, разумеется.
На практике это нередко "что-то не получилось, но забыли такой вариант обработать и пытаемся вызвать метод". Т.е. необязательно не получилось и ничего нельзя было поделать, может и можно было, но вот забыли. А Option просто не дает забыть обрабатывать такие случаи.
Ну как не даёт - вроде как Java не даёт не обрабатывать эксепшены, так тут же начинают писать catch(Exception e) { /* TODO */ } и так прямо в продакшен и пихают.
А, кстати, NPE относится к тем checked exceptions? Java разве заставляет все обращения к методам и полям в try-catch заворачивать на случай NPE?
То, что ленивый человек может замять обработку None явно (каким-то аналогом catch(Exception e) { /* TODO */ }), это конечно правда, но все ж это не то же самое, что просто забыть.
В общем да, с опшеном тa же фигня получается, если народ пишет option.get(). В этих всех скальных классах есть некоторое количество лишних функций, делающих фп несколько бессмысленным.
В высоконадежном программировании применяют расширенную типизацию и гард-выражения. Суть что в типе можно указать только те значения, для которых функция протестирована, соответственно виртмашина пристреливает процесс с ошибкой типа синего экрана, стектрейсом итп, естественно в некоторых пределах возможны всяческие try с обработкой ошибки. Гард-выражения в сущности делают то же, что расширенные типы, но чуть другой синтаксис и проверка находится на входе в функцию и позволяет применять бюилтин функции виртмашины. Пример - if (x%2 == 0)
Для невычислимого применяется аналитическое доказательство - ну например, что корень квадратный при вещественной арифметике, определен только для положительных чисел.
На практике, в реально критических приложениях (самолеты/ракеты/спутники) диапазон входных значений очень сильно ограничен физикой - например, типичный самолет на 10+км просто в принципе летит на скорости 800км/ч +-10км/ч - если больше может развалиться, если меньше - упадет, так что и смысла нет тестировать за пределами этого диапазона - важно только чтобы эту цифирь тщательно и безошибочно вписали в контракт (см "контрактное программирование"). - Например, самая дорогая в истории программная ошибка, как раз и случилась от того что на "Ариан-5" реиспользовали софт от "Ариан-4", а в контракте не учли что "Ариан-5" летает выше и быстрее чем "Ариан-4".
no subject
Date: 2014-07-16 03:11 pm (UTC)no subject
Date: 2014-07-16 09:09 pm (UTC)no subject
Date: 2014-07-16 09:49 pm (UTC)Во втором случае само сообщение абсурдно. Хотя спасибо, что написали because. Но тут же мы как бы имеем дело с контролем версий - ну так и ведите себя реалистично; мерж, может быть, какой-нибудь. Глупо же удивляться неожиданностям и валить все это на юзера.
no subject
Date: 2014-07-16 11:42 pm (UTC)Т.е. либо надо каждую функцию оснастить специальной рассказывалкой (что в общем случае невозможно - есть же библиотеки), либо в конце концов будут всё равно случаи вида "что-то не так, а что - неизвестно, вот вам бектрейс".
no subject
Date: 2014-07-17 12:23 am (UTC)no subject
Date: 2014-07-17 07:47 am (UTC)На практике это нередко "что-то не получилось, но забыли такой вариант обработать и пытаемся вызвать метод". Т.е. необязательно не получилось и ничего нельзя было поделать, может и можно было, но вот забыли. А Option просто не дает забыть обрабатывать такие случаи.
no subject
Date: 2014-07-17 08:06 am (UTC)no subject
Date: 2014-07-17 08:31 am (UTC)То, что ленивый человек может замять обработку None явно (каким-то аналогом catch(Exception e) { /* TODO */ }), это конечно правда, но все ж это не то же самое, что просто забыть.
no subject
Date: 2014-07-17 09:00 pm (UTC)no subject
Date: 2014-07-16 11:17 pm (UTC)Суть что в типе можно указать только те значения, для которых функция протестирована, соответственно виртмашина пристреливает процесс с ошибкой типа синего экрана, стектрейсом итп, естественно в некоторых пределах возможны всяческие try с обработкой ошибки.
Гард-выражения в сущности делают то же, что расширенные типы, но чуть другой синтаксис и проверка находится на входе в функцию и позволяет применять бюилтин функции виртмашины.
Пример - if (x%2 == 0)
no subject
Date: 2014-07-16 11:44 pm (UTC)А не упарятся на 2^64 значений тестировать? А если аргументов пять?
no subject
Date: 2014-07-17 12:57 am (UTC)no subject
Date: 2014-07-17 01:07 am (UTC)- Например, самая дорогая в истории программная ошибка, как раз и случилась от того что на "Ариан-5" реиспользовали софт от "Ариан-4", а в контракте не учли что "Ариан-5" летает выше и быстрее чем "Ариан-4".