Re[7]: Result objects - все-таки победили Exceptions?
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.01.25 11:13
Оценка:
Здравствуйте, Andir, Вы писали:
A>Абсолютно такое же ощущение/практика. Единственно, что это не только с исключениями так работает, но и с кодами возврата, и с просто некорректными результатами ака "обычно не бывает" — которые просто игнорируются, пока это возможно, если "не давать по рукам". У исключений есть даже преимущество в этом случае — они хотя бы не игнорируются по умолчанию, а вылетают выше уровнем и их легче задетектать, чем проигноренный результат от которого никаких следов может и не остаться к моменту неадекватного поведения.
То, о чём вы говорите — тяжкое наследие "ассемблерноподобных" языков с рудиментарными системами типов.
Если вы пишете на ассемблере, то совершенно логичными являются всякие неявные соглашения вроде "мы возвращаем не int index, а некий алгебраический тип, устроенный так: если это положительное нечётное число — то index-1 это указатель на word; если положительное чётное — то x/2 даст нам само значение; если число отрицательное — то это код ошибки".
К моменту обработки вся эта тонкая семантика потеряна, т.к. в момент записи в регистр эта штука становится просто битами. Корректная их интерпретация — забота программиста; у компилятора просто нет информации, достаточной для отличения корректного кода от некорректного.

А современные языки оборудованы, в том числе, и exhaustiveness-checking. То есть если у меня тип значения — это "number | string", то мне недостаточно просто обложить арифметическую операцию с ним проверкой вида if(x is number) return x + 1;. Компилятор может и должен бить меня по рукам, "э-э-э, а ты не написал, что делать если там string!".
Строгая типизация сильно помогает в таких случаях. Но сильно упарываться в эту сторону становится контрпродуктивным, т.к. сложные системы типов становятся некомфортными в использовании как для разработчика, так и для компилятора.
Имеет смысл дополнять автовывод типов явными пред/пост условиями. Их преимущество по сравнению с императивными проверками — в том, что компилятор может попытаться статически доказать их корректность; в случае заведомой некорректности он даст по рукам; в случае заведомой корректности он едет дальше; в случае невозможности доказательства — оставляет проверки в рантайме.

Скажем, я бы не стал выражать концепцию "коллекция, отсортированная по возрастанию" в терминах системы типов. Громоздко и неэффективно.
А вот записать это требование в предусловиях метода бинарного поиска — норм. Современные системы верификации прекрасно
а) проверяют, что метод sort реально возвращает отсортированный массив, а не всякий мусор
б) в случае, если на вход методу binary_search подаётся неотсортированный массив, бьют программиста по рукам
в) в случае, если на вход методу binary_search подаётся массив, который был только что отсортирован, не тратят такты на проверку факта отсортированности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.