Информация об изменениях

Сообщение Re[2]: Еще по Nullable/Optional от 24.12.2014 22:04

Изменено 24.12.2014 22:05 vsb

Здравствуйте, NeoCode, Вы писали:

NC>Еще один вопрос — по реализации.

NC>Допустим, язык программирования для ссылочных типов будет поддерживать опциональность естественным путем — для любого ссылочного типа ссылка на NULL это None.

NC>Для типов, представленных по значению, естественно должна поддерживаться внешняя реализация optional<T> — полностью включающая поля класса T и дополнительное поле тега, которое равно None или Some. Эта реализация должна быть полностью совместима со ссылками на null (в плане сравнения объектов, поведения, преобразования одного представления в другое и т.п.)


NC>Но потенциально есть еще одна возможность. Можно добавить в язык программирования поддержку "none-конструктора". Это специальный конструктор объекта, который конструирует объект с внутренним состоянием, которое для этого класса объектов считается невалидным.


null значение даёт удобную возможность не ставить проверки на каждый чих. При разыменовании нулевого указателя процессор сгенерирует прерывание и программа получит сигнал от ОС (вроде так всё происходит). В общем runtime без лишних инструкций получает проверки в нужных местах. Другие варианты будут требовать проверок во всех сомнительных местах и это может быть хуже по производительности.

А так вариант вполне рабочий. float/double неиспользуемый найти можно, там есть "особые" значения. unsigned int – 2^32-1. signed int – -2^31. Разве что может быть непривычно, что эти значения непредставимы. Придётся отрабатывать много всяких корневых случаев, обзятально делать ошибки при переполнении (впрочем это к лучшему). Значение меньше 4 байтов можно просто представлять 4-мя байтами и всё, там вообще проблем нет. Но куча лишних инструкций будет, либо хитрые оптимизации, всё равно не всегда работающие.

NC>С одной стороны вроде удобно (не нужно дополнительных оберток, памяти на них), но с другой — непонятно во что это выльется. Ведь можно в программе явно (без none-конструктора) создать такой объект простым присваиванием полей. И как с ним работать дальше? По идее, с ним нельзя работать дальше, т.к. формально он равен "none", и нужно сразу же выбрасывать исключение.


Тут всё просо. Говорим, что значения 2^32-1 у нас нет и всё тут. Кто-то сделал (2^32-2) + 1? Просто кидаем integer overflow exception и всё. Главное это определяь побыстрее и подешевле.

NC>Также, если объект держал какие-то ресурсы, и вдруг "случайно" стал none, ресурсы остались неосвобожденными и пропали? В общем фигня получается.


Этот момент я не очень понял. Чем это отличается от указателя, который держал какие то ресурсы и стал null? Что вообще значит случайно?
Здравствуйте, NeoCode, Вы писали:

NC>Еще один вопрос — по реализации.

NC>Допустим, язык программирования для ссылочных типов будет поддерживать опциональность естественным путем — для любого ссылочного типа ссылка на NULL это None.

NC>Для типов, представленных по значению, естественно должна поддерживаться внешняя реализация optional<T> — полностью включающая поля класса T и дополнительное поле тега, которое равно None или Some. Эта реализация должна быть полностью совместима со ссылками на null (в плане сравнения объектов, поведения, преобразования одного представления в другое и т.п.)


NC>Но потенциально есть еще одна возможность. Можно добавить в язык программирования поддержку "none-конструктора". Это специальный конструктор объекта, который конструирует объект с внутренним состоянием, которое для этого класса объектов считается невалидным.


null значение даёт удобную возможность не ставить проверки на каждый чих. При разыменовании нулевого указателя процессор сгенерирует прерывание и программа получит сигнал от ОС (вроде так всё происходит). В общем runtime без лишних инструкций получает проверки в нужных местах. Другие варианты будут требовать проверок во всех сомнительных местах и это может быть хуже по производительности.

А так вариант вполне рабочий. float/double неиспользуемый найти можно, там есть "особые" значения. unsigned int – 2^32-1. signed int – -2^31. Разве что может быть непривычно, что эти значения непредставимы. Придётся отрабатывать много всяких угловых случаев, обзятально делать ошибки при переполнении (впрочем это к лучшему). Значение меньше 4 байтов можно просто представлять 4-мя байтами и всё, там вообще проблем нет. Но куча лишних инструкций будет, либо хитрые оптимизации, всё равно не всегда работающие.

NC>С одной стороны вроде удобно (не нужно дополнительных оберток, памяти на них), но с другой — непонятно во что это выльется. Ведь можно в программе явно (без none-конструктора) создать такой объект простым присваиванием полей. И как с ним работать дальше? По идее, с ним нельзя работать дальше, т.к. формально он равен "none", и нужно сразу же выбрасывать исключение.


Тут всё просо. Говорим, что значения 2^32-1 у нас нет и всё тут. Кто-то сделал (2^32-2) + 1? Просто кидаем integer overflow exception и всё. Главное это определяь побыстрее и подешевле.

NC>Также, если объект держал какие-то ресурсы, и вдруг "случайно" стал none, ресурсы остались неосвобожденными и пропали? В общем фигня получается.


Этот момент я не очень понял. Чем это отличается от указателя, который держал какие то ресурсы и стал null? Что вообще значит случайно?