Комментарии 33
Это база, ловить NPE на проде)
Тут ещё наверное вторая сторона медали присутствует. Крайняя ограниченность вычислительных ресурсов в 1965 году... Для реализации небезопасного "null" сколько байт кода в самом компиляторе надо? А для реализации "Option<T>" со всеми условиями?
“Как Rust обманывает процессор: тайная жизнь niche-оптимизации, drop flags и MIR” https://habr.com/ru/articles/1031398/
Это Вы говорите про результирующий код программы. Там, да, во многих случаях абстракции системы типов не приводят к разрастанию программы. Но коллега говорит о размере и сложности компилятора, а не скомпилированной программы. Компиляторы 60-х были куда проще современного компилятора Rust.
Ну и в целом чтобы придумать как именно это решать даже с небольшими ресурсами надо десяток лет пожить с этой ошибкой в проде. Щас-то с послезнанием хорошо говорить “это было ошибкой”.
В Java компилятор молчал, и ты узнавал о проблеме в проде. В Rust компилятор не даёт собрать программу, пока ты явно не ответишь на вопрос «а если тут пусто?». Дырку в стене вернули обратно в чертёж — и заварили на этапе компиляции.
Явно типизированный концепт Maybe лучше, чем автоматическое наложение этого концепта на вообще всё. Но он встречается настолько часто, что "для удобства" сделали unwrap и expect, которые втыкают в каждое второе место. В результате джависты смотрят на NPE в проде, а растисты - на креши всего продукта в проде.
Вместо работы с проблемой сказали "у нас ее нет, подпишите вот здесь что осознаете риск и берете ответственность" и как-бы вынесли за пределы безопасной безопасности языка.
А когда проблему игнорируют, то получается еще хуже.
Я бы сказал что NPE хуже unwrap() в том смысле, что unwrap сразу виден и его, например, поиском по коду можно найти. А вот с местами, где разименовывается указатель всё не так просто, места где может возникнуть NPE не так очевидны
Самое интересное началось как раз после того доклада 2009 года. Языки, которые проектировали уже с оглядкой на признание Хоара, эту дырку начали заделывать — каждый по-своему, но в одну сторону: отсутствие значения должно быть видно в типе, и компилятор должен заставить тебя его обработать.
В Haskell это Maybe. В Rust — Option<T>, и raw-null там просто нет как класса
Ну позвольте, это всё как минимум в Standard ML'е или даже в Hope появилось, к моменту этого доклада этому типу в том или ином виде минимум лет 20-30
Это примерно как вопрос почему Страуструп не реализовал ООП как надо было по Аллану Кею.
Потому что "правильный" способ работал слишком медленно.
Во-первых, не понимаю чего тут плюсуют. Статья сделана при помощи ИИ, но не в этом суть.
Во-вторых. ИЗВИНИЛСЯ??? За то, что создал null???
Ну не создал бы он, создал бы кто-нибудь другой. Потому что как без null? Разве кто-то хочет, чтоб ссылки вели куда-нибудь не туда, лишь бы не были null?
Ну не создал бы он, создал бы кто-нибудь другой.
Я абсолютно согласен с тем, что кто-нибудь в каком-нибудь языке высокого уровня обязательно сделал бы nil - это слишком напрашивающееся решение, это просто индикатор указателя, которому не присвоено значение; естественная альтернатива этому - случайное значение (что ещё хуже), а вовсе не современные абстрактны средства систем типов. nil ведь как раз и был придуман как дешёвый способ отличить неинициализированный указать от инициализированного.
Если бы Хоар в языке Algol-W сделал бы умную обработку ситуации с неинициализированными указателями, то, естественно, языков с корректной обработкой (с умной системой типов) было бы больше - потому что многие языки позаимствовали многие идеи из Алгола; а имеющих эту проблему - меньше. Но, думаю, вряд ли очень уж сильно. В Алголе были различные навороты, от которых при проектировании других языков отказались ради простоты и производительности, и от этого наворота отказались бы в пользу обычного null.
Да и похожая идея, по большому счёту, придумана независимо в Си - null-terminated string, пожалуй.
Разве кто-то хочет, чтоб ссылки вели куда-нибудь не туда, лишь бы не были null?
Речь не об этом, речь о языковых конструкциях, вынуждающих программиста использовании указателей ("разыменовании указателя") обрабатывать ситуацию, когда указатель не инициализирован, а не продолжать использовать его, как будто он инициализирован. Введение nil позволило программисту проверять, инициализирован ли указатель, но не заставило его это делать.
Разве кто-то хочет, чтоб ссылки вели куда-нибудь не туда, лишь бы не были null?
Не очень в тему, но напомнило параллельный мем:
Скрытый текст

Хоар в тот момент проектировал систему типов для ALGOL W — по сути, первую серьёзную, всеобъемлющую систему типов для ссылок в объектно-ориентированном языке
ALGOL W - не объектно-ориентированный язык. Но если вы знаете о неизвестных работах Хоара в этой области, то это хорошая тема для следующей статьи
А в C# точнее в ADO.NET еще есть DBNull
А вот в современном C#/.NET есть типы string? и string. первый может указывать на null, второй - нет. дыра, наконец, закрыта?
Видимо вы плохо знаете современный си шарп: и там и там будет null, это ссылочный тип и защиты от null как только проверить if'ом на null нет.
Но тут нет проблемы, просто нужно себя приучать всегда проверять на null если может случиться Null reference exception
Это проверяется на уровне компилятора. Очень легко (банальным ! или ещё 10 способами засунуть туда null). Так что это просто небольшой сахар для удобного анализа, код в реальности не меняется никак.
для тех кому интересна история -
можно сказать Konrad Zuse Plankakul был в самом начале, примерно в 1949-50 он вел семинар и читал лекции в Мюнхене по архитектуре Z3, Z4 и компиляции Plankalkul, на этих семинарах впервые появились идеи по использованию стека, reverse polish notation и пр., участники приняли позже активное участие в проекте ALGOL-58


потребность в языках высокого языка была очевидна всем, но особенно при разработке больших систем реального времени, поэтому не ожидая окончания стандартизации на основе ALGOL-58 в US был создан JOVIAL, Julers Own Version of IAL, IAL = International Algebraic Language, так тогда называли ALGOL-58 в US, Jules (Jules Schwarz) один из его авторов, JOVIAL был основной язык программирования больших систем реального времени следующие 20 лет до появления ADA,
после стандартизации ALGOL-60, международный комитет продолжил работу, через несколько лет появился новый проект ALGOL W, и его конкурент ALGOL-68, который был одобрен как более продвинутый, позже ALGOL W стал основой PASCAL
А в чём суть вышеописанной проблемы? Пустая строка это пустая строка, и что? Или это необъявленная переменная? Я вроде не сталкивался с проблемой и падениями "все знакомы с этой бедой". Бригаду....
Не пустая строка, а отсутствие строки. Присутствие отсутствия вообще чего бы то ни было.
Проблема в том, что рано или поздно кто-то будет чинить совершенно специфический баг, который должен работать "ВЧЕРА!" и сооблазнится "меньшим злом" в виде "быстрого решения" - подготовить тип и передать посредством некой переменной в другую функцию, которая вызовет другую функцию, а та третью....
И проблема в том, что быстрое решение - не позволит ему подготовить объект "как надо" - одно из свойств подготовленного объекта будет NULL.... Но именно это свойство будет требоваться где-то в глубине стека функций, одна из которых вызовет подсвойство указанного свойства - то бишь буквально вызвав <ОбъектПередаваемогоТипа>.SubProperty..... Но у NULL, который упакован под видом <ОбъектПередаваемогоТипа> нет никаких SubProperty, SubFunction или прочей фигни, присущей полноценным объектам.... И при этом у NULL есть ссылка на тип, который, в подсказке среды разработки говорит, что "всё нормуль, SubProperty и SubFunction - ЕСТЬ!
И в результате ваша программа или сервис - гакнется на проде со свистом и со стеком, который она естественно скушает, потому что это Release билд, в котором обычно включают сокращённую трассировку.
Из плюсов: в джаве стали часто внедрить JSpecify, штука, которая призвана всё, не помеченное как @NonNull, и используемое без проверок на null, находить и помечать как warning. Ещё очень нравится как null реализован в котлине, там в целом нельзя засунуть null туда, где он не ожидается
ничего не падало, но один прикол был nul != null
На самом деле никакой проблемы нет и "ошибка на миллиард долларов" - это всего лишь маркетинговая уловка для продвижения котлина и прочих подобных языков.
NPE это всего лишь проблема упорядочивания, когда объект используется до инициализации. Такие ошибки ловятся и чинятся за пару секунд. Среди всех проблем встречаемых программистами эта находится где-то на 109 месте.

«Я не смог устоять»: как один человек в 1965-м добавил null, и оставил индустрии счёт на миллиард долларов