Я попытаюсь объяснить что именно меня заставляет постоянно испытывать когнитивный диссонанс при написании на ерланге. И пример из «Erlang programming» очень для этого подходит:
Допустим мы пишем функцию возвращающую номер месяца по его имени:
month('January') -> 1;
month('February') -> 2;
...
month('December') -> 12.
Что произойдёт, если вызвать эту функцию с «неправильным» параметром? Процесс упадёт, так как Ерланг не найдёт подходящей функции. А дальше у меня возникает «естественное» желание это отловить. Варианта три:
Совсем неправильный вариант — дописать
month(_other) -> {error, badmonth}.
Чуть менее неправильный вариант — переписать всё вот так:
month('January') -> {ok, 1};
month('February') -> {ok, 2};
...
month('December') -> {ok, 12};
month(_other) -> {error, badmonth}.
Особо изощренный неправильный вариант:
try
M = month(MonthName)
catch
_:_ -> ....
end
Есть еще варианты, но это, на самом деле, не важно. Потому что в этом месте ловить эту ошибку не нужно. Совсем не нужно. Оно должно упасть и пусть себе падает, всё равно никакого другого разумного выхода из этой ситуации нет, кроме как упасть и перезапуститься.
А почему приходится себя заставлять не делать эти проверки — это как раз «тяжелое наследие C/Pascal и иже с ним». Когда в течение многих лет приходилось помнить, что malloc может вернуть не только указатель, что fopen может вернуть не только хендл файла, когда неправильные параметры могут привести к не предсказуемым результатам.
Впрочем, я думаю, что у людей, которые начинали с чего-то более адекватного, хотя-бы с C++, я уж молчу про всякие Явы, нет такой проблемы. Они изначально знают, что функция или вернет что просят, или вывалится.