S>Какое вычисление(ну ладно, польза) без side effect'ов?
Return value, конечно же. И дело в "апологетстве", а в минимизации мест, где происходят side effects — для того, чтобы отладка всего этого не стала кошмаром. Дело в том, что любой side effect по сути своей является ничем иным как использованием "глобальной переменной". Которые ровно за этот самый недетерминизм и ругают.
S>И как добавлять эти метаданные без перехвата исключения на месте?
В тех местах, где таки надо снабдить пролетающее исключение — хватай, добавляй метаданные, прокидывай дальше.
Таких мест должно быть очень мало. Потому что если их много, отладка такой программы будет настоящим адом. Все-таки, эффективное программирование возможно только тогда, когда программа детерминированно делает что от нее ожидается. А не валится с рандомной диагностикой.
S>Это именно реальный мир. В огороженном вольере сидять как раз программисты на фп языках. Ну или
ФП тут не при чем, это вопрос грамотного дизайна. Детерминированное поведение ровно так же ожидается и от функций на все том же С++. Собственно, на этом базируется все авто-тестирование — подаются те самые детерминированные "моки", которые детерминированно возвращают ожидаемое значение.
Если совсем уж простой пример привести, если функции на языке С++ передать все данные, и никакие другие глобальные переменные та функция не использует, ее поведение должно быть детерминировано. Легко тестируемо, и вообще, о такой функции легко рассуждать (reasoning). Даже если кому-то поначалу сложно научиться (ну как же так, всю жисть глобальные переменные дергали, а тут вдруг низ-зя), это таки вопрос освоения мощных инструментов. Речь, разумеется, о тех участках кода, где эти инструменты применимы (это подавляющее большинство non-performance-critical кода).