Re[119]: Че ты лыбишься, хам трамвайный?
От: rg45 СССР  
Дата: 23.08.23 13:15
Оценка:
Здравствуйте, vopl, Вы писали:

V>это пять ящитаю


Щитай
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[112]: в холодной воде
От: B0FEE664  
Дата: 23.08.23 14:16
Оценка:
Здравствуйте, rg45, Вы писали:

σ>>Если программа constructed according to the syntax and semantic rules , а нарушение semantic rules, или ещё что-то подходящее под определение UB, возникнет во время её execution, то это никак не отменит well-formed

R>Если "возникнет", значит "not constructed according..." — все просто.

Если рассуждать формально, то неопределённое поведение при переполнении знакового целого — это следование правилу, а не нарушение правила. Нарушением правила бы было определённое поведение там, где должно быть неопределённое поведение.
И каждый день — без права на ошибку...
Re[113]: в холодной воде
От: rg45 СССР  
Дата: 23.08.23 14:19
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Если рассуждать формально, то неопределённое поведение при переполнении знакового целого — это следование правилу, а не нарушение правила. Нарушением правила бы было определённое поведение там, где должно быть неопределённое поведение.


Да понял я уже давно свою ошибку. Так, куражусь просто.

Характер скверный — предки виноваты

--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 23.08.2023 14:24 rg45 . Предыдущая версия .
Re[82]: Когда это наконец станет defined behavior?
От: vopl Россия  
Дата: 27.08.23 11:46
Оценка: +1
Здравствуйте, σ, Вы писали:

V>>Например:

V>>
σ>std::map<int, int> buildMap() {
σ>    std::map<int, int> result;

σ>    result.insert(42, 43); // мутабельность
σ>}

σ>const std::map<int, int> xxx = buildMap(); // сохранили в иммутабельный объект
σ>

σ>Вопрос с подвохом: что если происходит NRVO и result с xxx обозначают один и тот же объект. Он будет константным?

[cменяю мнение ]

В значительной мере вкурив это положение стандарта, лично я прихожу к выводу что на самом деле нет оснований полагать, что объект один.

In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object.


Мой перевод
В таких случаях, реализация трактует source и target в аспекте опущенной copy/move operation просто как два различных пути сослаться на один и тот же объект.

Моя трактовка
относительно опущенной copy/move operation
компилятор должен считать (имена/переменные) source и target
указывающими на один и тот же объект

То есть, "считать за один и тот же объект" — это только "в рамках выдавливания copy/move". Про любые другие аспекты речь не идет, следовательно, в них никакой не "один и тот же объект". Формально, декларация source и декларация target определяют два разных объекта, у каждого свой тип и все остальные свойства. И только лишь когда над ними производится выдавливание copy/move, то в рамках этого выдавливания "считаем что source и target указывают на один объект", не более.
Re[83]: Когда это наконец станет defined behavior?
От: rg45 СССР  
Дата: 27.08.23 11:58
Оценка: +1
Здравствуйте, vopl, Вы писали:

V>>>Например:

V>>>
σ>>std::map<int, int> buildMap() {
σ>>    std::map<int, int> result;

σ>>    result.insert(42, 43); // мутабельность
σ>>}

σ>>const std::map<int, int> xxx = buildMap(); // сохранили в иммутабельный объект
σ>>

σ>>Вопрос с подвохом: что если происходит NRVO и result с xxx обозначают один и тот же объект. Он будет константным?

V>[cменяю мнение ]


V>В значительной мере вкурив это положение стандарта, лично я прихожу к выводу что на самом деле нет оснований полагать, что объект один.

V>

In such cases, the implementation treats the source and target of the omitted copy/move operation as simply two different ways of referring to the same object.


V>Мой перевод

V>В таких случаях, реализация трактует source и target в аспекте опущенной copy/move operation просто как два различных пути сослаться на один и тот же объект.

V>Моя трактовка

V>относительно опущенной copy/move operation
V>компилятор должен считать (имена/переменные) source и target
V>указывающими на один и тот же объект

V>То есть, "считать за один и тот же объект" — это только "в рамках выдавливания copy/move". Про любые другие аспекты речь не идет, следовательно, в них никакой не "один и тот же объект". Формально, декларация source и декларация target определяют два разных объекта, у каждого свой тип и все остальные свойства. И только лишь когда над ними производится выдавливание copy/move, то в рамках этого выдавливания "считаем что source и target указывают на один объект", не более.


Даже если допустить, что формулировка кривовата, отказываться от подобного использования, опасаясь UB, лично я не стал бы.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[16]: Когда это наконец станет defined behavior?
От: Sm0ke Россия ksi
Дата: 27.08.23 16:03
Оценка:
Здравствуйте, rg45, Вы писали:

R>
R>int i;
R>const int& r = i;
R>r = 3;
R>


R>Ссылка на константный объект! А объект-то нифига не константный.


Ссылка на константный объект, которая проинициализирована не-кностантным lvalue.
Re[53]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 11:19
Оценка:
Здравствуйте, vdimas, Вы писали:

v> Ты намекаешь на отсутствие автоматического распространения константности по указателям и ссылкам?

Я ни на что не намекаю, просто ты теряешь контекст разговора. Моя реплика относится к "хеш-функцию пишется один раз". Нет, не пишется она один раз, т.к. в течение жизни проекта поля в объекте могут меняться и требовать модификаций этой функции.
Впрочем, в java завезли records, которые избавляют от этой необходимости.

v> Гарантии создаёт программист согласно требуемой семантике, разумеется.

v> Разумеется, и в джаве и в плюсах можно обеспечить все требуемые гарантии.
Зачем ты это мне всё рассказываешь? Я указал на ошибку в тезисе T4r4sB: "Как жаба следит чтоб ты не менял ключи хешмап? В С++ есть const. Этого достаточно.". Суть моего тезиса в том, что const не достаточно и в C++ ситуация такая же как и в java — гарантии обеспечивает таки программист.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[59]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 11:24
Оценка:
Здравствуйте, vdimas, Вы писали:

v> ·>Я это прекрасно знаю. Ровно то же и в java. Просто T4r4sB заявил
Автор: T4r4sB
Дата: 12.05.23
, что в C++ есть какая-то защита в виде const. Да не даёт const ровным счётом ничего.

v> Даёт экономию труда примерно вдвое в обсуждаемых сценариях.
Речь шла не про экономию труда, а про гарантии корректности и защиту, подменой тезиса ты занимаешься. Да и неясно в чём ты намерял экономию. Используя record в java можно наэкономить раз в десять в некоторых случаях.

v> ·>Только если либо копия передаётся, либо передача ownership, и это немного помогает в некоторых случаях, но возможностей стрельнуть в ногу всё равно дофига.

v> Возможностей стрельнуть себе в ногу дофига где угодно.
v> Тут рассуждения такие: меньше кода — меньше ошибок.
Спорное утверждение. Элементарно опровергаемое — прогнав прогу через обфускатор легко уменьшить количество кода, оставив число ошибок ровно таким же.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 28.08.2023 11:25 · . Предыдущая версия .
Re[58]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 11:31
Оценка:
Здравствуйте, vdimas, Вы писали:

v> reference_wrapper хранит ссылку как значение, т.е. придаёт ссылке св-ва указателя.

v> Соотв, когда будешь описывать операторы сравнения для reference_wrapper, сравнивать надо identity ссылаемых объектов, а не содержимое.
Искать в мапе, как правило, надо по содержимому.

v> В любом случае, пример твой некорректен согласно логике спора, бо ты пытаешься рассуждать об потенциальных ошибках обеспечения константности-иммутабельности, где ошибки можно допустить и в джаве (и где угодно) в попытках обеспечения этой иммутабельности.

Это твои фантазии. Перечитай.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[81]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 11:41
Оценка:
Здравствуйте, vdimas, Вы писали:


v> В шарпе для такого сценария есть отдельно иммутабельный аналог map, и отдельно мутабельный builder для него.

v> В С++ не потребовалось создавать две сущности.
Ровно те же две сущности тоже: "map" и "const map". Просто синтаксис чуток отличается.

v> Этот сценарий может возникнуть не только вокруг иммутабельного map, где в шарпе постелили соломку, а вообще везде.

Этот сценарий может возникнуть не только вокруг константности, а вообще везде. В C++ подстелили соломку, взяв легаси от C, а интерфейсы могут покрыть любую семантику. Например, "очередь в которую можно только добавлять, но ничего нельзя удалять" — вполне может оказаться полезным интерфейсом.

v> Собсно, только об этом и говорится в обсуждении (многократно по кругу) — что практически любой мутабельный тип можно использовать в т.ч. в иммутабельных сценариях.

Не любой, а тот для которого аккуратно задизайнен const-набор методов.

v> Остальные сценарии, когда мутабельный объект подаётся по константной ссылке — это просто удобные гарантии, т.к. после вызова метода с таким аргументом ты можешь в коде рассуждать о том, что целевой объект в результате вызова некоей ф-ии с им-аргументом, не изменился.

Ровно это же обеспечивается и соответсвующим интерфейсом.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[83]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 12:28
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Интерфейсы и в плюсах доступны.

В С++ с ними связаны накладные расходы.

V>И прочие GOF-трюки, где иммутабельность может быть св-вом объекта, а может быть адаптером-view.

Иммутабельность нельзя через view обеспечить. Ты тоже что-ли путаешь константность и иммутабельность?
Константность означает, что объект нельзя поменять. А иммутабельность, что объект не может поменяться.

V>Просто это слишком частый сценарий, поэтому органично включён в язык, дабы достигать того же самого без лишних приседаний.

Что считать приседаниями и стоят ли они такого значительного усложнения системы типов языка — вопрос очень спорный. Но я от этого спора уклонюсь.

V>·>А две сущности в C++ тоже есть, просто неявно. Вместо явного интерфейса делается пара const- и просто-методов.

V>Так мы только выразительность языков и обсуждаем.
Обсуждение началось с вопроса о том, что константность вещь очень важная и нужная и в других ЯП без неё всё плохо. Мой тезис в том, что это вовсе не так, и множество других ЯП прекрасно обходятся без константности.

V>·>Константные объекты появляются не магически, а в определениях соответствующих полей и методов.

V>И в правилах языка, где константные методы можно вызывать у неконстантного объекта, а наоборот нет.
В шарпах-явах то же самое выражается в виде системы типов с интерфейсами и наследованием.

V>Например, св-во size() (count, amount и т.д.) определены как const, соответственно, описаны однажды для константного и неконстантного объекта.

V>И всё это продолжает работать в таких сценариях:
V>logCollection(cl); // отдали куда-то по константной ссылке
Насчёт выразительности — читая этот код — здесь это никак не выражено. И никак не проверяется компилятором. Завтра вася поменяет определение logCollection, потеряет или сломает константность — и приехали.

V>for(size_t i = 0; i < size; i++) // незачем запрашивать размер коллекции заново

Ну это удобство для компилятора, а не для человека. В яве с этим мучается обычно JIT.

V>·>И там и там надо вводить два типа. Ведь T и const T это тоже разные типы.

V>Да.
V>Но описание типа программистом — одно.
В каком смысле "одно"? Можно описать в соседних строчках файла? Или что? Чем описание интерфейса "другее"?

V>Т.е., итераторы на интерфейсах сделаны не только потому что невозможно было накрутить логику как в плюсах через begin/end (в нынешнем шарпе уже можно сделать достаточно близко к плюсовомоу подходу, получив дешевизну), но еще потому что ДРУГОЙ интерфейс обеспечивает ДРУГУЮ семантику. В данном случае IEnumerator — это read-only семантика, т.е. употребима к мутабельным и немутабельным типам. В итоге для каждой коллекции приходится описывать еще и енумератор.

V>А вот если речь должна идти про сами типы-коллекции, то появляются пары Span/ReadOnlySpan, Memory/ReadOnlyMemory и т.д.
И что в этом плохого-то? Чем таким принципиально важным "const Span" отличается от "ReadOnlySpan"?

V>И это еще в шарпе по-лёгкoму, т.к. язык позволяет определять операторы преобразования, поэтому смогли определить неявное конструирование ReadOnly-версий из мутабельных.

V>В джаве пришлось бы делать двойную работу, окучивая каждую пару.
Ну в джаве в похожем месте другой дизайн — там буферы, readonly означает, что можно читать данные (при этом сам буфер как объект меняется — сдвигается position и т.п.), но записывать данные нельзя. Что-то похожее на memory mapped file, открытый с ro-правами.

V>>>Остальные сценарии, когда мутабельный объект подаётся по константной ссылке — это просто удобные гарантии, т.к. после вызова метода с таким аргументом ты можешь в коде рассуждать о том, что целевой объект в результате вызова некоей ф-ии с им-аргументом, не изменился.

V>·>Аналог final.
V>Не, final-метод в джаве обозначает другое.
final-поле и final-переменная я имею в виду.

V>·>Суть моего тезиса в том, что семантика const в других ЯП выражается тоже, просто через другие механизмы языка.

V>Суть в том, что иммутабельность — такой же "трюк", облегчающий программистам жизнь, как и куча других.
Разговор о том, насколько этот трюк необходим, начался разговор с того, что "как же в других ЯП без него обходятся", я рассказал как.

V>И тут С++ задолго до, как грится, оказался к этому готов. ))

V>А вот почему более поздние джава и шарп оказались не готовы — вопрос вопросов, однако.
В java есть record, давно уже готово.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[84]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 28.08.23 16:48
Оценка:
Здравствуйте, ·, Вы писали:

V>>И прочие GOF-трюки, где иммутабельность может быть св-вом объекта, а может быть адаптером-view.

·>Иммутабельность нельзя через view обеспечить.

Обеспечить-то программным образом можно, ес-но.
Нельзя обеспечить, скажем, контроль иммутабельности со стороны компилятора, т.е. нельзя задать гарантии через ср-ва языка.


·>Ты тоже что-ли путаешь константность и иммутабельность?


Применительно к данным — это одно и то же.
Применительно к ссылкам/указателям на данные — необходимо уточнять, что имеется ввиду — константность указателя или самих данных.

Константность можно добавлять неиммутабельным данным по ссылке/указателю, убирать константность нельзя.
То бишь, для любых константных данных их иммутабельность автоматически гарантируется.

Код, принимающий аргументы по константной ссылке или указателю, может быть одинаков для иммутабельных и неиммутабельных объектов (в части их const-интерфейса) — как прямое следствие возможности добавления к типу модификатора const по указателю/ссылке.


·>Константность означает, что объект нельзя поменять. А иммутабельность, что объект не может поменяться.


ха-ха
Это в тебе говорит прокуренность джавой, где ты вместо переменной ссылочного типа видишь сам объект за ним.

В плюсах такая константность раздается независимо как переменной-указателю, так и указуемым данным:
const SomeObj * const obj = getObj();

Переменная obj является иммутабельной, инициализирована указателем на объект типа const SomeObj.


V>>Просто это слишком частый сценарий, поэтому органично включён в язык, дабы достигать того же самого без лишних приседаний.

·>Что считать приседаниями и стоят ли они такого значительного усложнения системы типов языка — вопрос очень спорный.

Насчёт "значительно" перебор, ИМХО, бо правила вокруг const просты, даже слишком.


·>Но я от этого спора уклонюсь.


Потому что спор бесполезный.
Сравнивалась выразительность языков, где бесполезно сравнивать декларативные пометки внутри одного класса с описанием доп. классов (разделение на builder и immutable-версии одной и той же структуры данных).


V>>Так мы только выразительность языков и обсуждаем.

·>Обсуждение началось с вопроса о том, что константность вещь очень важная и нужная и в других ЯП без неё всё плохо.

Больше работы — плохо.
Это и есть "выразительность".


·>Мой тезис в том, что это вовсе не так, и множество других ЯП прекрасно обходятся без константности.


1. Обходятся за счёт лишнего труда программиста.
2. Присутствует принципиальная сложность обеспечить константность для ссылочных типов, иначе это было бы давно сделано.

Спроси меня "почему?" — растолкую подробно, почему в C# аналог const есть только для структур, но не может быть применён к классам.
Это не в недостатке машинки дотнета дело, а в семантике ссылочно-ориентированных языков.

Повторюсь:

·>Ты ... путаешь константность и иммутабельность?
Применительно к данным — это одно и то же.



V>>·>Константные объекты появляются не магически, а в определениях соответствующих полей и методов.

V>>И в правилах языка, где константные методы можно вызывать у неконстантного объекта, а наоборот нет.
·>В шарпах-явах то же самое выражается в виде системы типов с интерфейсами и наследованием.

Но компилятор умывает руки, бо это контракты прикладного уровня, которые легко нарушить.
Плюсовые контракты нарушить сложнее во много раз.
(разве что через реинтерпретацию/хак памяти, но аналогичные ср-ва есть и в дотнете, и в джаве, вроде)


·>Насчёт выразительности — читая этот код — здесь это никак не выражено. И никак не проверяется компилятором. Завтра вася поменяет определение logCollection, потеряет или сломает константность — и приехали.


Сломает через хак, если.
А законными ср-вами сложно.


V>>for(size_t i = 0; i < size; i++) // незачем запрашивать размер коллекции заново

·>Ну это удобство для компилятора, а не для человека. В яве с этим мучается обычно JIT.

JIT и компиляторы не всесильны, они хорошо работают только в простейших случаях (где никакого const и не надо, бо компилятор и без сопливых видит жизиненный цикл данных).
Обсуждаемое помогает именно там, где никакой JIT и компилятор уже не справляются.


V>>·>И там и там надо вводить два типа. Ведь T и const T это тоже разные типы.

V>>Да.
V>>Но описание типа программистом — одно.
·>В каком смысле "одно"? Можно описать в соседних строчках файла? Или что? Чем описание интерфейса "другее"?

Тем, что по интерфейсу не гарантируется иммутабельность — компилятор умывает руки.
А если в плюсах создал const-объект, то он достоверно иммутабельный (с точностью до замечания о распространении константности по ссылочным полям, где решение я давал).


V>>А вот если речь должна идти про сами типы-коллекции, то появляются пары Span/ReadOnlySpan, Memory/ReadOnlyMemory и т.д.

·>И что в этом плохого-то? Чем таким принципиально важным "const Span" отличается от "ReadOnlySpan"?

Тем, что достаточно было одного типа Span, некоторые св-ва и методы которого помечены как const (и эти методы и св-ва уже и так присутствуют, просто без пометки).


V>>И это еще в шарпе по-лёгкoму, т.к. язык позволяет определять операторы преобразования, поэтому смогли определить неявное конструирование ReadOnly-версий из мутабельных.

V>>В джаве пришлось бы делать двойную работу, окучивая каждую пару.
·>Ну в джаве в похожем месте другой дизайн — там буферы, readonly означает, что можно читать данные (при этом сам буфер как объект меняется — сдвигается position и т.п.), но записывать данные нельзя. Что-то похожее на memory mapped file, открытый с ro-правами.

В этом случае достаточен readonly итератор, т.е. некий view над иммутабельными данными.


V>>Не, final-метод в джаве обозначает другое.

·>final-поле и final-переменная я имею в виду.

Бгг, что намекает о том, что пользовательских value-типов в джаве никогда не будет. ))
Ведь в шарпе повторили семантику const для них, где соотв. методы помечены как readonly, т.е. другое ключевое слово (аналог final-классов и final-методов в шарпе sealed).


V>>Суть в том, что иммутабельность — такой же "трюк", облегчающий программистам жизнь, как и куча других.

·>Разговор о том, насколько этот трюк необходим, начался разговор с того, что "как же в других ЯП без него обходятся", я рассказал как.

И малость засверкал наивностью, бо все и так прекрасно в курсе, как обходятся в других ЯП.
А ты стал лишь подтверждать исходные тезисы. ))

(Вряд ли для плюсовкиа его язык единственный или хотя бы первый, для нашего поколения он шёл обычно вторым-третьим языком, т.е. на плюсы подсаживались обычно более чем сознательно).


V>>А вот почему более поздние джава и шарп оказались не готовы — вопрос вопросов, однако.

·>В java есть record, давно уже готово.

Ну какой давно, пару лет еще не прошло.
В котлине дата-классы давнее.
И это закрывается только малая часть сценариев вокруг иммутабельности.
Re[85]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 28.08.23 19:33
Оценка: :)
Здравствуйте, vdimas, Вы писали:

V>>>И прочие GOF-трюки, где иммутабельность может быть св-вом объекта, а может быть адаптером-view.

V>·>Иммутабельность нельзя через view обеспечить.
V>Обеспечить-то программным образом можно, ес-но.
Нет, нельзя. Ты не можешь сделать иммутабельный view к мутабельному объекту. Вообще никак, это просто бессмысленно. Можно сделать read-only view, но не иммутабельный view.

V>Нельзя обеспечить, скажем, контроль иммутабельности со стороны компилятора, т.е. нельзя задать гарантии через ср-ва языка.

Можно создать иммутабельный объект копируя мутабельные данные, ну или через передачу владения, собственно всё. Ну или если у тебя какой-нибудь rust с borrow checker.

V>·>Ты тоже что-ли путаешь константность и иммутабельность?

V>Применительно к данным — это одно и то же.
V>Применительно к ссылкам/указателям на данные — необходимо уточнять, что имеется ввиду — константность указателя или самих данных.
Указатель — это тоже вид данных, не надо мудрствовать.

V>Константность можно добавлять неиммутабельным данным по ссылке/указателю, убирать константность нельзя.

V>То бишь, для любых константных данных их иммутабельность автоматически гарантируется.
Иммутабельность гарантируется только тогда, когда к данным нет легального способа получить мутабельный доступ.

V>Код, принимающий аргументы по константной ссылке или указателю, может быть одинаков для иммутабельных и неиммутабельных объектов (в части их const-интерфейса) — как прямое следствие возможности добавления к типу модификатора const по указателю/ссылке.

Это не достаточное условие. У типа должны быть какие-то определённые const-методы (или, другими словами, const-интерфейс). Иначе наличие такой ссылки тебе ничего не даст, т.к. не сможешь ничего сделать. В чём разница с интерфейсами — неясно.

V>·>Константность означает, что объект нельзя поменять. А иммутабельность, что объект не может поменяться.

V>ха-ха
V>Это в тебе говорит прокуренность джавой, где ты вместо переменной ссылочного типа видишь сам объект за ним.
Ерунда какая-то. В точности наоборот, в джаве все объекты — только по ссылке.

V>В плюсах такая константность раздается независимо как переменной-указателю, так и указуемым данным:

V>
V>const SomeObj * const obj = getObj();
V>

V>Переменная obj является иммутабельной, инициализирована указателем на
ну в случае final SomeObj obj = getObj() в яве тоже, переменная тоже "иммутабельная". Правда толку маловато будет. Применять термин Иммутабельность к переменной — как-то бессмысленно, только для разведения демагогии годится. Мутабельность-иммутабельность обычно относится к состоянию объекта.

V> объект типа const SomeObj.

Ага. А вот тут уже интереснее — именно что const-объекта, но про иммутабельность — ичсх ты промолчал. Демагогия, ЧТД.

V> Насчёт "значительно" перебор, ИМХО, бо правила вокруг const просты, даже слишком.

Только что тут флейм был на сотню сообщений что где когда с константностью происходит. Ага, ага, всё просто.

V>·>Но я от этого спора уклонюсь.

V>Потому что спор бесполезный.
Потому что бесмысленный, основанный на субъективщине и вкусовщине.

V>Сравнивалась выразительность языков, где бесполезно сравнивать декларативные пометки внутри одного класса с описанием доп. классов (разделение на builder и immutable-версии одной и той же структуры данных).

Если ты таки поймёшь разницу между константностью и иммутабельностью, то поймёшь, что в плюсах ситуация ровно такая же.

V>>>Так мы только выразительность языков и обсуждаем.

V>·>Обсуждение началось с вопроса о том, что константность вещь очень важная и нужная и в других ЯП без неё всё плохо.
V>Больше работы — плохо.
А в чём работу меряешь-то? Пишешь record, вешаешь @Builder аннотацию и готово. Да даже без этого, с современной IDE работу делает железяка, а не программист.

V>·>Мой тезис в том, что это вовсе не так, и множество других ЯП прекрасно обходятся без константности.

V>1. Обходятся за счёт лишнего труда программиста.
Этот труд давно автоматизирован и поэтому не программист трудится.

V>2. Присутствует принципиальная сложность обеспечить константность для ссылочных типов, иначе это было бы давно сделано.

V>Спроси меня "почему?" — растолкую подробно, почему в C# аналог const есть только для структур, но не может быть применён к классам.
Потому что они статик? Имхо, просто ошибка в проектировании семантики языка.

V>Это не в недостатке машинки дотнета дело, а в семантике ссылочно-ориентированных языков.

Ну в общем-да. Но ты говоришь, как будто это что-то плохое, называешь недостатком.

V>·>Ты ... путаешь константность и иммутабельность?

V>Применительно к данным — это одно и то же.
В этом случае есть final в джава. Но это неинтересный случай, а демагогия.

V>>>И в правилах языка, где константные методы можно вызывать у неконстантного объекта, а наоборот нет.

V>·>В шарпах-явах то же самое выражается в виде системы типов с интерфейсами и наследованием.
V>Но компилятор умывает руки, бо это контракты прикладного уровня, которые легко нарушить.
V>Плюсовые контракты нарушить сложнее во много раз.
V>(разве что через реинтерпретацию/хак памяти, но аналогичные ср-ва есть и в дотнете, и в джаве, вроде)
В целом да, цена универсальности. Зашивать конкретный контракт в спеку ЯП — очень тяжелая артиллерия. Имхо, в данном случае, неоправданная. Но это _имхо_. Спорить не буду.

V>·>Насчёт выразительности — читая этот код — здесь это никак не выражено. И никак не проверяется компилятором. Завтра вася поменяет определение logCollection, потеряет или сломает константность — и приехали.

V>Сломает через хак, если.
V>А законными ср-вами сложно.
Какой хак? Было logCollection(const X&), потом вдруг немного что-то понадобилось где-то и поменял на logCollection(X&), а код всё ещё компиляется как ни в чём не бывало. А в плюсах ошибка в размере типично ведёт к UB и оно даже может как-то работать.

V>>>for(size_t i = 0; i < size; i++) // незачем запрашивать размер коллекции заново

V>·>Ну это удобство для компилятора, а не для человека. В яве с этим мучается обычно JIT.
V>JIT и компиляторы не всесильны, они хорошо работают только в простейших случаях (где никакого const и не надо, бо компилятор и без сопливых видит жизиненный цикл данных).
V>Обсуждаемое помогает именно там, где никакой JIT и компилятор уже не справляются.
Ну идея JIT в том, что таких простейших случаев 99.9%, а там где оно не справилось, там попрофилируем и пооптимизируем вручную.

V>·>В каком смысле "одно"? Можно описать в соседних строчках файла? Или что? Чем описание интерфейса "другее"?

V>Тем, что по интерфейсу не гарантируется иммутабельность — компилятор умывает руки.
Иммутабельность (не путай с константностью) и в плюсах ничем не может гарантироваться. Ты сам вроде это мне доказывал. А аналог const есть и в java в виде final.

V>А если в плюсах создал const-объект, то он достоверно иммутабельный (с точностью до замечания о распространении константности по ссылочным полям, где решение я давал).

А как ты достоверно создашь const-объект-то? Ну тот же std::map, например? В лучшем случае через defensive copy или через передачу владения. Ровно так же как и в шарпах-явах.

V>>>А вот если речь должна идти про сами типы-коллекции, то появляются пары Span/ReadOnlySpan, Memory/ReadOnlyMemory и т.д.

V>·>И что в этом плохого-то? Чем таким принципиально важным "const Span" отличается от "ReadOnlySpan"?
V>Тем, что достаточно было одного типа Span, некоторые св-ва и методы которого помечены как const (и эти методы и св-ва уже и так присутствуют, просто без пометки).
Я имею в виду с т.з. программиста? Реальная причина в том, что им приходится Span делать как struct и избегать боксинга, т.е. просто реализовать ифейс они не не могут. Проблема в компиляторе, в оптимизации, а не в выразительности для человека.

V>>>И это еще в шарпе по-лёгкoму, т.к. язык позволяет определять операторы преобразования, поэтому смогли определить неявное конструирование ReadOnly-версий из мутабельных.

V>>>В джаве пришлось бы делать двойную работу, окучивая каждую пару.
V>·>Ну в джаве в похожем месте другой дизайн — там буферы, readonly означает, что можно читать данные (при этом сам буфер как объект меняется — сдвигается position и т.п.), но записывать данные нельзя. Что-то похожее на memory mapped file, открытый с ro-правами.
V>В этом случае достаточен readonly итератор, т.е. некий view над иммутабельными данными.
Ну там довольно сложный набор методов — взятие данных различных размеров, по разным позициям и т.п. По сути итератор и есть, но очень навороченный, заточенный для обработки бинарных блоков.

V>>>Не, final-метод в джаве обозначает другое.

V>·>final-поле и final-переменная я имею в виду.
V>Бгг, что намекает о том, что пользовательских value-типов в джаве никогда не будет. ))
Ну вроде Valhalla пилят, правда с низким приоритетом...

V>Ведь в шарпе повторили семантику const для них, где соотв. методы помечены как readonly, т.е. другое ключевое слово (аналог final-классов и final-методов в шарпе sealed).

Не понял что к чему.

V>>>Суть в том, что иммутабельность — такой же "трюк", облегчающий программистам жизнь, как и куча других.

V>·>Разговор о том, насколько этот трюк необходим, начался разговор с того, что "как же в других ЯП без него обходятся", я рассказал как.
V>И малость засверкал наивностью, бо все и так прекрасно в курсе, как обходятся в других ЯП.
V>А ты стал лишь подтверждать исходные тезисы. ))
V>(Вряд ли для плюсовкиа его язык единственный или хотя бы первый, для нашего поколения он шёл обычно вторым-третьим языком, т.е. на плюсы подсаживались обычно более чем сознательно).
Судя по обсуждению — далеко не все в курсе.

V>>>А вот почему более поздние джава и шарп оказались не готовы — вопрос вопросов, однако.

V>·>В java есть record, давно уже готово.
V>Ну какой давно, пару лет еще не прошло.
До этого — lombok если очень хотелось.

V>В котлине дата-классы давнее.

И в scala case-классы ещё давнее.

V>И это закрывается только малая часть сценариев вокруг иммутабельности.

А что не закрывается?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 28.08.2023 21:54 · . Предыдущая версия .
Re[13]: Почему?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 31.08.23 06:20
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>CLANG

S>
S>f1():                                 # @f1()
S>        xorl    %eax, %eax
S>        retq
S>


S>p/s: это при -O2


S>Почему?


x в f1 неинициализирован. Оптимизация в одной функции это видит быстрее, чем в двух разделённых. Неициализировано => в LLVM есть специальная отработка undef и poison значений, которая по сути сводится к "выбирай что больше нравится, всё одно там фигня".
В принципе компилятор мог и вообще убрать запись чего-то в eax, но вот решил оставить.
The God is real, unless declared integer.
Re[14]: Почему?
От: Sm0ke Россия ksi
Дата: 31.08.23 16:27
Оценка:
Здравствуйте, netch80, Вы писали:

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


S>>CLANG

S>>
S>>f1():                                 # @f1()
S>>        xorl    %eax, %eax
S>>        retq
S>>


S>>p/s: это при -O2


S>>Почему?


N>x в f1 неинициализирован. Оптимизация в одной функции это видит быстрее, чем в двух разделённых. Неициализировано => в LLVM есть специальная отработка undef и poison значений, которая по сути сводится к "выбирай что больше нравится, всё одно там фигня".

N>В принципе компилятор мог и вообще убрать запись чего-то в eax, но вот решил оставить.

Тип переменной известен на этапе компиляции как bool.
Исходя из логики выражение { bool x; return x||!x; } должно возвращать всегда true, независимо от значения x. И при значении x = true, и при значении x = false.
Операторы для bool не перегружены пользователем, ответ однозначен. Как оптимизатор будет это осуществлять: методом перебора, или уметь упрощать логические выражения — не так важно.

Если оптимизатор не может некий случай упростить с корректным результатом, то лучше пусть не упрощает.
Даже если стандарт позволяет при чтении неинициализированной переменной (UB) лепить компилятору что угодно.


Ещё пример:
#include <iostream>

int f1(int p) { int x; return p + x * 0; }

int f2(int p) { int x; return p + (x - x); }

int main()
{
  std::cout << f1(5) << '\n';
  std::cout << f2(5) << '\n';
  return 0;
}

Тут оптимизатор справляется
Re[86]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 31.08.23 18:05
Оценка:
Здравствуйте, ·, Вы писали:

V>>>>И прочие GOF-трюки, где иммутабельность может быть св-вом объекта, а может быть адаптером-view.

V>>·>Иммутабельность нельзя через view обеспечить.
V>>Обеспечить-то программным образом можно, ес-но.
·>Нет, нельзя. Ты не можешь сделать иммутабельный view к мутабельному объекту. Вообще никак, это просто бессмысленно. Можно сделать read-only view, но не иммутабельный view.

Заканчивай уже употреблять слова, смысла которых не понимаешь. ))
Если протечек ссылок для мутабельности нет, то автоматом получается иммутабельность.


V>>Нельзя обеспечить, скажем, контроль иммутабельности со стороны компилятора, т.е. нельзя задать гарантии через ср-ва языка.

·>Можно создать иммутабельный объект копируя мутабельные данные

Или литералы-константы, или другие иммутабельные объекты.


·>ну или через передачу владения, собственно всё.


Ес-но.
Об этом и речь, что иммутабельность целиком переезжает на прикладной уровень в джаве, а компилятор умывает руки.
Стоило ли ради этого столько постов трепыхаться? ))


V>>·>Ты тоже что-ли путаешь константность и иммутабельность?

V>>Применительно к данным — это одно и то же.
V>>Применительно к ссылкам/указателям на данные — необходимо уточнять, что имеется ввиду — константность указателя или самих данных.
·>Указатель — это тоже вид данных, не надо мудрствовать.

Именно, как и ссылочная переменная в джаве.
А ты лишь опять сотрясал воздух без понимания определений. ))


V>>Константность можно добавлять неиммутабельным данным по ссылке/указателю, убирать константность нельзя.

V>>То бишь, для любых константных данных их иммутабельность автоматически гарантируется.
·>Иммутабельность гарантируется только тогда, когда к данным нет легального способа получить мутабельный доступ.

Молодец!
Иммутабельность — это иммутабельность!

А константа — это константа!
И для обычных даных это в точности равно иммутабельности.
А для ссылочных данных константность может быть как "приобретаемым позже" свойством, так и неотъемлимым, приобретаемым непосредственно после создания данных (объекта).
Ву а ля!

Я ХЗ где ты тут в 3-х соснах плутаешь. ))


V>>Код, принимающий аргументы по константной ссылке или указателю, может быть одинаков для иммутабельных и неиммутабельных объектов (в части их const-интерфейса) — как прямое следствие возможности добавления к типу модификатора const по указателю/ссылке.

·>Это не достаточное условие.

Это не условие, дурилки картонные, это св-ва инструментария!

Нет абсолютно никакой потребности обеспечивать иммутабельность типа таком коде, достаточно гарантий, что этот код работает в т.ч. с иммутабельными данными.

Это банальное перепендикулярное разделение данных и кода!

Ладно, тут всё ясно.
Кажется, я понял причину твоих трудностей, что ты тут простыни кода исписал уже, ходишь по кругу. ))

Ты зачем-то рассматривал данные и обрабатывающий его код как нечто неразрывное, верно?

Т.е. умудрился в упор не заметить, что иммутабельные и read-only сценарии существенно пересекаются (read-only сценарии являются строгим подмножеством иммутабельных сценариев).

Так вот, иммутабельность обеспечивается на уровне данных и более никак.
А код пишется как read-only или нет.
И на выходе у нас комбинаторика сценариев, а не сумма их.
Отредактировано 31.08.2023 18:06 vdimas . Предыдущая версия . Еще …
Отредактировано 31.08.2023 18:05 vdimas . Предыдущая версия .
Re[87]: Когда это наконец станет defined behavior?
От: · Великобритания  
Дата: 31.08.23 19:10
Оценка:
Здравствуйте, vdimas, Вы писали:

v> V>>·>Иммутабельность нельзя через view обеспечить.

v> V>>Обеспечить-то программным образом можно, ес-но.
v> ·>Нет, нельзя. Ты не можешь сделать иммутабельный view к мутабельному объекту. Вообще никак, это просто бессмысленно. Можно сделать read-only view, но не иммутабельный view.
v> Заканчивай уже употреблять слова, смысла которых не понимаешь. ))
А ты заканчивай коньяк по утрам пить и таки покажи пример кода как обеспечить иммутабельность через view мутабельного объекта.

v> Если протечек ссылок для мутабельности нет, то автоматом получается иммутабельность.

Это я и написал ниже.
Вопрос в том, как же компилятор проверяет/помогает гарантировать отстуствие протечек с помощью const? Ответ — да никак. Вывод — const бесполезен для иммутабельности.

v> ·>Можно создать иммутабельный объект копируя мутабельные данные

v> Или литералы-константы, или другие иммутабельные объекты.
Не понял твоё дополнение. Ты предлагаешь копировать литералы-константы, или другие иммутабельные объекты? Зачем? Важное свойство иммутабельных объектов в том, что их копии никак не отличимы от оригинала и копирование можно избегать.

v> ·>ну или через передачу владения, собственно всё.

v> Ес-но.
v> Об этом и речь, что иммутабельность целиком переезжает на прикладной уровень в джаве, а компилятор умывает руки.
Как и в Плюсах.

v> ·>Указатель — это тоже вид данных, не надо мудрствовать.

v> Именно, как и ссылочная переменная в джаве.
v> А ты лишь опять сотрясал воздух без понимания определений. ))
Ты сотрясал воздух отвечая на вопросы, которые никто не задавал.

v> V>>То бишь, для любых константных данных их иммутабельность автоматически гарантируется.

v> ·>Иммутабельность гарантируется только тогда, когда к данным нет легального способа получить мутабельный доступ.
v> Молодец!
v> Иммутабельность — это иммутабельность!
v> А константа — это константа!
Ровно твои слова же: "Если протечек ссылок для мутабельности нет, то автоматом получается иммутабельность". К чему сарказм-то?

Вопрос в том, как собственно обеспечить отсутствие протечек. И где что там у тебя автоматически гарантируется-то с помощью const?
Допустим, у тебя есть где-то const SomeThing someValue(42); — ты гарантируешь, что someValue — иммутабельно?

v> И для обычных даных это в точности равно иммутабельности.

Повторюсь. Данные — не объекты (если я правильно понял, что ты подразумеваешь под данными). Мы говорим об объектах.

v> А для ссылочных данных константность может быть как "приобретаемым позже" свойством, так и неотъемлимым, приобретаемым непосредственно после создания данных (объекта).

v> Ву а ля!
Приобретаемым как? Только заботой программиста. Компайлер c const ничего гарантировать не может.
В java record — гарантии есть, кстати.

v> Я ХЗ где ты тут в 3-х соснах плутаешь. ))

Ты вообще в двух соснах запутался. Да, каждый иммутабельный объект — константный, но это скучно. Важно то, что не каждый константный объект — иммутабельный. Следовательно константность никак не гарантирует иммутабельности. Это ложится на программиста, что в плюсах, что в джаве, что в шарпах. const для иммутабельности не нужен. Нужен record.

v> ·>Это не достаточное условие.

v> Это не условие, дурилки картонные, это св-ва инструментария!
v> Нет абсолютно никакой потребности обеспечивать иммутабельность типа таком коде, достаточно гарантий, что этот код работает в т.ч. с иммутабельными данными.
Так откуда ты берёшь эти гарантии-то? Рассказывай уже, не томи.

v> Ты зачем-то рассматривал данные и обрабатывающий его код как нечто неразрывное, верно?

Иммутабельность она и в африке иммутабельность.

v> Т.е. умудрился в упор не заметить, что иммутабельные и read-only сценарии существенно пересекаются (read-only сценарии являются строгим подмножеством иммутабельных сценариев).

Нет, не подмножеством. read-only view для мутабельного объекта — не подмножество иммутабельного сценария, ну никак.

v> Так вот, иммутабельность обеспечивается на уровне данных и более никак.

v> А код пишется как read-only или нет.
v> И на выходе у нас комбинаторика сценариев, а не сумма их.
Осталось понять ценность этого комбинаторного усложнения на ровном месте, это и есть основная тема этого обсуждения. Мой тезис в том, что иммутабельность — нужна и важна, константность — не является необходимостью и можно нафиг выкинуть, что собственно и сделали в шарпах-явах. Тогда нафиг никакой комбинаторики и всё просто.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[88]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 01.09.23 23:27
Оценка:
Здравствуйте, ·, Вы писали:

v>>Заканчивай уже употреблять слова, смысла которых не понимаешь. ))

·>А ты заканчивай коньяк по утрам пить

Без обид, но упор на жонглирование терминами всегда попахивает эзотерикой, эдакой попыткой наделить известные вещи некими новыми характеристиками, которые "собеседник наверняка недопонимает" (С).


·>покажи пример кода как обеспечить иммутабельность через view мутабельного объекта.


Легко — достаточно обеспечить отсутствие протекание ссылки на мутабельный объект.
(например, создавать приватный мутабельный объект в конструкторе view)


·>Вопрос в том, как же компилятор проверяет/помогает гарантировать отстуствие протечек с помощью const?


Достаточно просто — объявляешь данные как const и они автоматом становятся иммутабельными.

Иммутабельность автоматически распространяется при владении другими объектами по-значению.
При владении по указателю/ссылкам я давал хелпер для автоматического распространения иммутабельности.


·>Ответ — да никак.


Для этого необходимо показать хотя бы минимальный пример этого "никак".


·>Вывод — const бесполезен для иммутабельности.


Вывод — ты споришь о том, что недостаточно изучил, походу.


·>Важное свойство иммутабельных объектов в том, что их копии никак не отличимы от оригинала и копирование можно избегать.


Это лишь один из трюков, достижимых при иммутабельности.
Так же как шаренье иммутабельных данных без блокировки м/у потоками.

Но иммутабельные данные необходимо как-то создавать.
И наиболее эффективно их создавать в мутабельной манере.
Я уже отсылал к паттерну mutable_builder => immutable_object.

Вот после создания иммутабельного объекта, все эти трюки можно использовать.


v>> ·>ну или через передачу владения, собственно всё.

v>> Ес-но.
v>> Об этом и речь, что иммутабельность целиком переезжает на прикладной уровень в джаве, а компилятор умывает руки.
·>Как и в Плюсах.

В плюсах компилятор больно бъёт тебе по пальцам.
Собсно, новички в плюсах зачастую маются с компиллированием программ именно из-за попыток нарушения константности.


·>Ровно твои слова же: "Если протечек ссылок для мутабельности нет, то автоматом получается иммутабельность". К чему сарказм-то?


К тому, что компилятор в плюсах отслеживает попытки "протечек" и отказывается компилировать такой код.


·>Вопрос в том, как собственно обеспечить отсутствие протечек.


#include <iostream>
#include <unordered_map>

using namespace std;

// ключ
struct index {
  int a;
  int b;

  index(int a, int b) : a(a), b(b) {}

  bool operator==(const index &) const = default;
};

// хеш-функция для ключа
template<> struct std::hash<index> {
  size_t operator()(const index & i) const {
    hash<int> h;
    return h(i.a) ^ h(i.b) << 1;
  }
};

// хеш-таблица
typedef unordered_map<index, string> SomeDictionary;

// фабрика оперирует мутабельным объектом
SomeDictionary buildDictionary() {
  SomeDictionary result;

  result[{42, 43}] = "42, 43";
  result[{44, 45}] = "44, 45";

  return result;    
}

// но здесь иммутабельный объект
const SomeDictionary dict = buildDictionary();

int main()
{
  cout << dict.at({42, 43}) << endl;
  return 0;
}

Параметром шаблона хеш-таблицы выступает тип index, но в качестве ключа хеш-таблицы используется const index.
Такова спецификация, см. value_type тут:
https://en.cppreference.com/w/cpp/container/unordered_map


·>И где что там у тебя автоматически гарантируется-то с помощью const?


В данном примере гарантируется, что переменная dict иммутабельная, хотя на этапе построения мы пошагово мутировали значение.
Но даже в процессе мутации ключи таблицы были гарантированно иммутабельны.


·>Допустим, у тебя есть где-то const SomeThing someValue(42); — ты гарантируешь, что someValue — иммутабельно?


Без хаков если, то да.


v>> И для обычных даных это в точности равно иммутабельности.

·>Повторюсь. Данные — не объекты (если я правильно понял, что ты подразумеваешь под данными). Мы говорим об объектах.

Ты опять разбрасываешься терминами.

Объект — это не только термин из ООП-парадигмы. В плюсах объектами является всё, даже простой int.

Данные/значения — это термин из механики происходящего, где by ref или by value имеют однозначную интерпретацию.

Соотв., экземпляры одного и того же типа могут храниться как "просто данные", т.е. по значению, или могут быть ссылаемы через ссылку/указатель.


v>> А для ссылочных данных константность может быть как "приобретаемым позже" свойством, так и неотъемлимым, приобретаемым непосредственно после создания данных (объекта).

v>> Ву а ля!
·>Приобретаемым как? Только заботой программиста. Компайлер c const ничего гарантировать не может.

Например, так:
const SomeObject * obj = new SomeObject();

Здесь оператор new возвращает указатель на неконстантный объект, но мы его сохраняем в указатель на константный объект.
Если конструктор SomeObject не имеет побочных эффектов (не сохраняет указатель на себя где-нить в глобальной переменной, т.е. если нет протечек), то гарантии получаются железобетонные.

Примечание, сам указатель не является иммутабельным, его можно перезаписать другим экземпляром const SomeObject *.
Для иммутабельности самого указателя перед ним надо написать еще один const.


·>В java record — гарантии есть, кстати.


Я ж не против, чтобы компилятор помогал программисту.
Это его прямая обязанность. ))

Да, в плюсах можно разрабатывать достоверно иммутабельные типы данных:
struct immutable_index {
    const int a;
    const int b;
};

но какой смысл объявлять еще один тип данных, если можно сделать так:
using immutable_index = const index;

автоматом унаследовав всю инфраструктуру вокруг исходного типа, например, вычисление хеш-функции.


·>Важно то, что не каждый константный объект — иммутабельный. Следовательно константность никак не гарантирует иммутабельности.


Опять напоминаю, что константностей несколько разных — константность по значению и по ссылке.
По значению — всегда иммутабельность.
По константной ссылке/указателю ты можешь ссылаться на мутабельные и иммутабельные объекты, делая код ортогональным для данных.


·>Это ложится на программиста, что в плюсах, что в джаве, что в шарпах. const для иммутабельности не нужен. Нужен record.


Это вам в джаве нужен, т.к. иммутабельность обеспечивается прикладной семантикой, где record — лишь синтаксический сахар для такой семантики.

Сравни с тем, что в примере выше index не является иммутабельным типом, т.е. может использоваться в мутабельных сценариях.
Но в типе SomeDictionary const index резко становится иммутабельным.


v>> Нет абсолютно никакой потребности обеспечивать иммутабельность типа таком коде, достаточно гарантий, что этот код работает в т.ч. с иммутабельными данными.

·>Так откуда ты берёшь эти гарантии-то? Рассказывай уже, не томи.

Показал выше и рассказал:
— константные данные (объекты, хранимые по-значению) всегда иммутабельны;
— ссылки на константные данные не гарантируют константность тех данных, они накладывают ограничения — позволяют использовать лишь иммутабельное АПИ объектов.


v>> Ты зачем-то рассматривал данные и обрабатывающий его код как нечто неразрывное, верно?

·>Иммутабельность она и в африке иммутабельность.

Да нет, в базе есть данные и алгоритмы над данными.
Определённым классом алгоритмов являются алгоритмы над неизменяемыми данными.

Как именно данные случаются неизменяемыми — да как угодно.
Можно и безо-всяких const, record, final и прочих приблуд, достаточно того, чтобы в момент работы таких алгоритмов данные никто не изменял.

Тут мы рассуждаем лишь о том, как защититься от случайного изменения невнимательным программистом данных, которые мы хотим рассматривать как иммутабельные.

В общем, подход плюсов оказался настолько удобным, что его перетянули и в C# (но только для value-типов) и даже в последние версии FreePascal.
Ранее в этих языках был доступен только подход джавы.


v>> Т.е. умудрился в упор не заметить, что иммутабельные и read-only сценарии существенно пересекаются (read-only сценарии являются строгим подмножеством иммутабельных сценариев).

·>Нет, не подмножеством. read-only view для мутабельного объекта — не подмножество иммутабельного сценария, ну никак.

Еще как подмножество.
В полном наборе иммутабельных сценариев CRUD отсуствует CUD в read-only сценариях. ))
(сосредоточься, плиз)


v>> И на выходе у нас комбинаторика сценариев, а не сумма их.

·>Осталось понять ценность этого комбинаторного усложнения на ровном месте

Наоборот, упрощение, бо комбинаторный подход позволяет упростить базу — меньше писать.
Одним и тем же кодом в плюсах ты можешь проходиться по мутабельному и иммутабельному дереву, например.
В джаве тебе пришлось бы делать два типа дерева и два кода для их обхода (или выкручиваться через интерфйесы, что утяжеляет/тормозит).


·>Мой тезис в том, что иммутабельность — нужна и важна


Допустим.
Хотя, так можно сказать о любом достаточно широком классе алгоритмов.


·>константность — не является необходимостью


Разумеется, константность не является необходимостью для иммутабельных сценариев.
Она лишь дико экономит труд програмиста и размер конечного бинаря, а так-то фигня полная.


·>и можно нафиг выкинуть, что собственно и сделали в шарпах-явах.


Наоборот, в шарпе вот относительно недавно добавили.
А потом опять добавили.
Ключевое слово чуть другое — readonly, но смысл и сценарии использования те же.


·>Тогда нафиг никакой комбинаторики и всё просто.


Сложнее, обычно.
Причём, гораздо.
Вплоть до того, что даже в иммутабельных сценариях в джаве редко кто заморачивается с внутренней гарантией этой иммутабельности.

В плюсах ведь доступен подход джавы, но это ж издевательство над психикой, поэтому никто так не делает.
Бо програмисты — народ ленивый. ))
Re[114]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 02.09.23 22:18
Оценка:
Здравствуйте, vopl, Вы писали:

V>по стандарту объект создается того типа который был при его декларации


Он и создаётся того типа. ))


V>а деклараций две, это явная коллизия, зря мы тут копья ломаем


const не меняет лейаут объекта, а лишь ограничивает допустимый АПИ этого объекта.

Т.е., я не вижу никакой коллизии если сначала создать лейаут объекта в памяти, а потом ограничить его АПИ согласно модификатора const.

Это как сослаться на неконстантный объект по константной ссылке.
Согласно твоим рассуждениям — как так???
Это мы на некий тип ссылаемся как будто на другой тип? Ай-ай-ай! ))


V>по моим данным, "const" это часть свойства "тип" объекта


Модификатор типа.


V>Настаиваю что по формулировкам стандарта — это один объект.


Убрали пару деструктор+конструктор в "физике" происходящего, но "в уме"-то не убираем! ))
Соответственно, согласно семантики можно считать, что старый объект умер, а на его месте родился новый, точно такой же.

Я ж предлагал уже удалить конструктор копирования для проверки семантики.


V>Чуствую что скоро будет иметь место какой нибудь дефект-репорт, типа "NRVO makes an object type collision ...blabla"


Ни в коем случае.
Иначе бы ты не мог ссылаться константными ссылками на неконстантные объекты, если бы в этом месте возникала коллизия.
Re[106]: Когда это наконец станет defined behavior?
От: vdimas Россия  
Дата: 02.09.23 22:33
Оценка:
Здравствуйте, vopl, Вы писали:

V>>Для UB недостаточно декларации — с объектом надо что-то "делать", чтобы наблюдать "поведение", которое вы обещали "потенциально неопределённое".

V>Для UB достаточно выполнить эти условия:

Any attempt to modify a const object during its lifetime results in undefined behavior.

И эти условия выполнены.


Это не все условия, бо UB, согласно термина, рассматривает исключительно и только некое поведение в рантайм, которое не может быть специфицировано стандартом, т.е. разные компиляторы или разные данные могут вызывать разное (неопределённое) поведение.


V>>До возврата из ф-ии с объектом ничего сделать нельзя.

V>а это уже не важно

Тогда исчезает буква B из термина UB. ))
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.