Здравствуйте, hi_octane, Вы писали:
_>Я в твоём сообщении не могу отделить ошибки от исключений. А хочется определённости — в итоге-то что? Парсеру json, если пришёл битый, что делать — кидать "просто ошибку" или исключение, которое приведёт к закрытию программы?
Не надо ничего кидать. Парсер json возвращает алгебраическую сумму из "ожидаемый тип объекта" и "ошибка синтаксиса".
Что с этим делать — решает пользователь этого парсера. Он может прямо тут же заматчить ошибку синтаксиса и, скажем, подставить дефолтный конфиг; или сделать retry, или просто прокинуть результат выше по стеку, делегировав принятие решения туда. Компилятор будет бить по рукам за попытку прочитать значение параметра из экземпляра типа "myConfig | BadSyntax".
_>Ну и чтоб два раза не вставать — выход за границу массива это ошибка или исключение, которое должно всё сломать? А невозможность выделить память?
Всё то же самое. Корректный тип у функции типа malloc<T>(n: int) — это не T[], а T[] | OutOfMemory. Поэтому перед тем, как пользоваться полученным указателем, программист вынужден его проверять. А не просто надеяться на то, что память всегда выделиться ("у меня никогда не возвращался нулевой указатель"), и получить SegFault в произвольно далёкой от malloc точке. _>Самый прикол, что решение "исключения существуют, и это нормально, главное что мы их можем перехватывать и обрабатывать" — даёт универсальный и единообразный подход к самым разным проблемам. А вот подход — "у нас в языке исключений нет, ну может чуть-чуть, на донышке" — приводит к тупику. Решение rust как раз в духе, в моём понимании, дибилизма — делайте всего по 2.
Не знаю насчёт Rust — никогда на нём не писал. Но вот моя практика работы с языками с исключениями — она как раз такая, что провоцирует людей писать в стиле "исключений не существует; бремя доказательства обратного лежит на QA". Это означает, что стоимость работоспособного кода очень сильно возрастает — первоначально написанный "оптимистичный" код уезжает в коммит, чтобы спустя дни и недели попасть в third-line support со словами "тут иногда что-то где-то крэшится, найдите и почините". Это гораздо, гораздо дороже, чем сразу заставить программиста написать код обработки.
Особенно если язык позволяет минимизировать бойлерплейт — например, при помощи автовывода типов.
Любой словарик из метода get(key: K) возвращает не V, а Maybe<V>, и нужно обязательно проверить, нашлось ли значение по ключу. А для типового случая есть перегрузка get(key: K, default: V), которая позволяет обойтись без паттерн-матчинга результата. Ну, или язык умеет в x: V = mydict.get(k) ?? defX; вместо x: V = mydict.get(k, defX);, и тогда даже и перегрузка не нужна.
То есть корректный код не сильно больше по объёму, чем некорректный, но зато он а) явный и б) надёжный.
Как по мне, так это именно то, к чему следует стремиться.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.