Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором. S>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки.
выполняет роль, но не является.
S>>Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям. Физический адрес я тоже не отношу к свойствам объекта. S>Подставив в твоё определение определение из википедии получаем: S>Логическая идентичность — это идентичность, основанная на отсутствии "википедия-идентичности". S>Здорово, правда?
Действительно здорово. Что-то я плохо спал
S>>Не прямые адреса, разве что. S>Нет. Ссылки имеют другую алгебру, чем адреса. S>Адреса можно сравнивать; можно вычитать. По адресу объекта можно определить, что он находится внутри другого объекта. S>Со ссылкой ничего подобного сделать нельзя. Поэтому не надо, пожалуйста, называть ссылки адресами.
Договорились.
S>>Следствие в википедии говорит об объектах одного типа. Откуда ты взял "для любого типа" — не знаю. S>Если бы следствие в википедии являлось действительно следствием, то его можно было бы формально доказать, исходя из определения там же. Увы.
Верно. Тем более, в исправленной форме это следствие действительно упоминается неоднократно.
Приближаюсь к объявлению капитуляции
S>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет. S>Смешные упражнения. Ок, пусть у нас будет ООП-система, в которой ссылки сравнивать нельзя — из неравенства ссылок не следует ничего интересного. Отлично, чтобы отличать объекты друг от друга, мы запихаем внутрь каждого экземпляра GUID. S>0. Этот GUID будет волшебным образом генерироваться при всяком создании объекта, будь то "с нуля" или при клонировании объекта. S>1. Этот ID будет недоступен коду самого объекта; его будет невозможно изменить в течение всего времени жизни. S>2. Сделаем волшебную функцию ID(obj), которая будет залезать внутрь объекта и возвращать его GUID. S>3. Объект никак не сможет повлиять на реализацию этой функции. S>Введённая нами функция ID удовлетворяет определению идентичности: она одинаковая для одного и того же объекта; она разная для разных объектов в силу 0; она не зависит от состояния объекта в силу 1; она не зависит от поведения объекта в силу 3.
Это своя реализация идентичности. Не интересно.
S>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>Не надо путать определение идентичности и реализацию идентичности. S>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода.
Для конкретной реализации — да.
S>>Нет. Это значит что из равенства ссылок следует identity. То что верно обратное ты не показал. Извини, в определении идентичности ничего про ссылки нет, поэтому тебе придется формально доказывать что идентичные объекты имеют равные ссылки. S>Да. Определение идентичности из ECMA — это memory location. Её применимость в качестве identity, если даже и не верить стандарту на слово, легко доказать.
memory location — это специальный случай. Он сильнее, чем то что подразумевается в определении идентичности. S>Осталось сделать одно из двух: S>1. найти место в ECMA, где сказано, что there cannot be two different references to the same memory location S>2. найти место в ECMA, где сказано, что сравнение ссылок заведомо определяет, ссылаются ли они обе на одно и то же memory location. S>На всякий случай поясню п.2: мы можем иметь ссылки, внутри устроенные как длинные указатели в DOS — пара (сегмент, смещение), где сегменты частично перекрываются. В такой схеме можно иметь две побитово различные ссылки на одно и то же место в памяти. S>Вариант 1 явно запрещает использование таких схем; вариант 2 разрешает использовать такие схемы, если есть подходящая реализация оператора == для таких ссылок.
Да, для ECMA понятия идентичности это верно. Но обобщить до определения идентичности в ООП это нельзя.
S>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL.
Компилировать FCL в C#-- не надо, нет такой цели S>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает.
Чихать что не заработает. Я не собираюсь удовлетворять ECMA-335. S>А если мы придумали способ, например ту самую волшебную функцию ID(obj), которая возвращает что-то сравнимое, не используя "биты" ссылки, то автоматически получаем реализацию оператора сравнения для ссылок: S>
Имеет смысл если ID вычислима. Но я не говорил что она вычислима.
S>>Незачем. Тебе C# позволяет привести ссылку к инвариантному формату? S>Конечно. Ссылка в C# уже имеет инвариантный формат.
Действительно.
S>>Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок. S>Зачем это доказывать? Это и есть определение идентичности.
В той трактовке, что позволяет отличать любой объект от всех остальных — да.
S>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений.
Ну дак мы их отличать можем в теории, по некой невычислимой функции. Существования такой функции достаточно, вычислимость ее — это просто очень полезный бонус
S>>добавим к C#-- то свойство, что ссылка включает в себя время ее получения. Вот такой я странный. G>>>3)Что будет identity в таком случае? S>>То же самое, см. формальное определение. G>>>4)Как отличать объекты один от другого? S>>Зачем? Механизм доставки сообщений по заданному identity работает. Большего не требуется. Я не собираюсь этот язык внедрять в производство или решать на нем какие-либо задачи. S>Механизма доставки по identity нету. Есть механизм доставки по ссылке. При таком определении ссылки вам ещё придётся доказывать, что ссылка имеет отношение к identity
мы можем отличать объекты с отличным поведением (но только их). Отличать объекты с неотличимым поведением не нужно. Но это уже видимо моя додумка.
S>>Я утверждаю что из неравенства ссылок может следовать same identity. S>Это утверждение очевидно неверно. При неравных ссылках same identity может быть, но вот следовать из них оно никак не может.
Про "следовать" погорячился. можем одновременно наблюдать неравенство ссылок и same identity.
S>>Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении. S>Такое определение идентичности не работает для изменяемых объектов. Потому что в течение жизни она у них будет изменяться.
Вот по этим изменениям я и предлагал определять идентичность.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Между строк читаю что ID не зависит от изменения состояний и поведения конкретного объекта. S>Это не между строк, это часть определения. S>>Но не вижу причин почему не отличать объекты по какой-то величине из области значений ID, которая имеет связь с поведением. S>Даже если отвлечься от противоречий с определением, у меня вызывает крайнее сомнение сама возможность формализации такого критерия.
Формализация есть. Вычислимости нет. S>Покажите мне схему реализации метода IsIdentic(o1, o2), которая гарантированно возвращает false для объектов с разным поведением, и true для объектов с одинаковым. Метод должен быть вычислимым, и не должен менять состояние объектов. Я не предполагаю конкретного языка программирования, но как вы себе это представляете?
Не представляю, и я писал об этом. Вы даже со мной тогда согласились. Гарантированно убедиться в идентичности поведения двух черных ящиков нельзя. Можно только опровергнуть, если сильно повезет.
S>>Без изменяемого поведения. Отсутствие изменяемого поведения — это тоже поведение. Не могу себе представить объект без поведения совсем. Ничего не делает — значит такое у него поведение. S>Чтобы вы начали себе представлять объект без поведения, желательно ввести формальное определение поведения. S>Можно попробовать по аналогии — начать представлять себе объект без состояния; (а то ведь можно сказать что "это у него такое состояние), а потом уже можно и без поведения представить.
Под объектом без состояния я понимаю объект без изменяемого состояния. При условии детерминированности оно же будет означать неизменность поведения.
S>>>2. Ваше предложение противоречит определению, которое требует от идентичности возможности различать разные объекты. S>>Оно позволяет различать объекты с разным поведением. S>Определение выдвигает более сильное требование — иметь возможность различать объекты независимо от поведения. А, значит, и объекты с одинаковым поведением.
Вычислять? Нет, там такого требования нет. Определять — да. Определить мы можем, предположив что дождались результата невычислимого ID.
S>>>Тем не менее, вы упорно приводите примеры, когда ваше определение идентичности приводит к неразличимости разных объектов. S>>Да, но разных объектов с неразличимым поведением. S>Мало ли что у них ещё неразличимо. Они разные — этого достаточно для несоответствия определению.
Это смущает.
Здравствуйте, samius, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, samius, Вы писали:
S>>>Но вот следствие из википедии S>>>
S>>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>>согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
G>>Это глупость написана. S>Это надо доказывать. G>>Банально опровергается сравнением ссылок. S>Для этого надо доказать что все идентичные объекты обладают равными ссылками. Формально.
Это в спецификации языка C# написано, синклер приводил. Для других языков можно найти аналогичное.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>надо поменять причину и следствие? Но тогда мы получим что-то не совсем осмысленное. S>>IF object identity of two objects of the same type is the same, THEN every change to either object is also a change to the other object. S>Мы получим почти точную перефразировку фразы, которую вы привели из другого источника.
Верно. За исключением same type.
S>>Для чего здесь уточнение same type? Что бы мы не взяли объекты с same identity но разного типа? Если забить на эту неувязку с same type, то в остальном — вполне осмысленная и верифицируемая фраза. Если бы она была в таком виде в википедии я бы не удивился. S>Если это следствие, то оно должно выводиться из определения. Кокретно это следствие никак не выводится.
Да.
S>>Я вижу что я понимаю смысл термина не так как остальные на этом форуме. Это для меня очевидно. S>И как все остальные в мире — тоже. Вы сами привели уже кучу ссылок. Везде получается так, что идентичность в ООП позволяет отличать любые объекты друг от друга.
Да S>Вне ООП можно определять идентичность по-другому. Но это будет уже не ООП.
Да.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали:
S>>Я еще помню что идентификатор это не ссылка. Правда это идентификатор не объекта, а переменной. Но все равно, я считаю что обошелся без ссылки. S>Ну и зря вы так считаете. А если я напишу MyObj &obj2 = obj, то ссылка появится?
Ссылка как понятие C++ появится, технически появится алиас.
Но вы скорее всего правы, идентификатор MyObj obj будет соответствовать понятию ссылки в ООП. S>Расскажите мне в деталях, чем obj2 семантически будет отличаться от obj.
S>>Согласно чему? S>Согласно определению ООП.
S>>Не вижу другого отношения. S>Ну как же, у вас всё время фигурирует какая-то "логическая идентичность", неуловимо отличающаяся от "физической идентичности", которой пользуются все остальные. Она, очевидно, вводит другое отношение между объектами, не такое, как у всех. Почему же вы его не видите?
А, в этом смысле? Другое отношение эквивалентности? Это да.
S>>Отлично. Я тоже признаюсь. Я готов признать вашу с ganjustas-ом правоту относительно трактовки идентичности. Единственное что меня еще смущает — я допускаю другую трактовку. Можно списывать на мою упертость, но я все-таки считаю что определение не вполне однозначно. И некоторые моменты все-таки наводят на сомения. S>Определение в ООП вполне однозначно. То, что вы пытаетесь ввести в качестве логической идентичности — это эквивалентность в смысле дотнетного стандарта.
Нет, я пытался ввести не это.
S>Для value-типов в дотнете она же принята за идентичность. S>Именно о ней же ведёт речь тот единственный чувак, который упомянул сам термин logical, or internal identity.
Он — да. Он о структурной эквивалентности.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, samius, Вы писали:
S>>>>Но вот следствие из википедии S>>>>
S>>>>The object identity of two objects of the same type is the same, if every change to either object is also a change to the other object.
S>>>>согласно ему a и b идентичны. Верно? Да и ссылка на same type есть, т.е. для любого типа это не надо показывать.
G>>>Это глупость написана. S>>Это надо доказывать.
Да, Sinclair мне уже открыл глаза на это.
G>>>Банально опровергается сравнением ссылок. S>>Для этого надо доказать что все идентичные объекты обладают равными ссылками. Формально.
G>Это в спецификации языка C# написано, синклер приводил. Для других языков можно найти аналогичное.
Будет время и силы — соберусь с мыслями и подумаю по поводу своего поведения. Прошу, не надо продолжать баталию.
Здравствуйте, samius, Вы писали: S>Что такое эквивалентность в смысле дотнетного стандарта? В ECMA-355 нет самостоятельного определения экивалентности, только упоминание ее в различных контекстах.
Вы опять как-то альтернативно читаете? Та же самая секция 8.2.5, подсекция 8.2.5.2 Equality.
S>структурная эквивалентность в смысле побитового совпадения областей памяти? Я пытался ввести эквивалентность поведения, что очевидно не то же самое, что структурная эквивалентность. Тогда ваше определение не совпадает даже с тем единственным местом, где хоть кто-то кроме вас вводит понятие логической идентичности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
S>>>Вот синклер написал что разные ссылки могут ссылаться на один объект. В таком случае идентичность этого объекта самому себе будет опровергнута. G>>Это зависит от реализации ссылки в языке, конкретно в C# ссылка и есть identity. А если в каком-то языке это не так, то там все равно есть способ получить некоторое инвариантное значение, которое мы и будем называть ссылкой. Например в БД это ключ записи. S>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором.
Тогда как отразить identity в языке? Чтобы их можно было сравнить у двух объектов.
S>>>>>ПОчему ты вообще используешь ссылки для определения идентичности? На каком формальном основании? Где в определении идентичности ссылки? Почему ты ссылку считаешь свойством объекта? G>>>>В концептуальном определении их нет, но реализация identity во всех известных мне языках с поддержкой ООП опирается на ссылки в том или ином виде. Вообще слабо себе представляю ООП без ссылок. S>>>Это не проблемы концепции. Допустим, в некой реализации ссылки нельзя сравнивать. Ты скажешь что это не ООП на том основании что в известных тебе реализациях это не так? G>>Ок, приведи такую реализацию. S>В этом нет необходимости.
Есть, иначе ты не можешь утверждать что такие существуют.
G>>Но это ты пытаешься сменить тему. По сути ты хотел доказать что неравенство ссылок в C# может быть и для идентичных объектов. Тебе то не удастся. Поэтому ты начала извращать понятие identity разводя демагогию. S>Ты слишком узко смотришь на определение идентичности.
Я смотрю на определения ровно так: http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm?OID/index.htm
При этом учитываю реализацию в современных языках.
S>>>Идентичность не зависит от поведения, но опираясь на наблюдаемое поведение можно опровергнуть логическую идентичность двух объектов. G>>Что такое логическая идентичность? S>Это идентичность, основанная на отсутствии свойств объектов, отличающих их. Под свойствами я подразумеваю не поля объекта и не свойства аксессоры к полям.
То есть поведение. Но по определению оно никаким боком к идентичности не относится.
S>Физический адрес я тоже не отношу к свойствам объекта.
Как выражается идентичность? Построй функцию id(object), чтобы id(a)==id(b) тогда и только тогда a и b совпадают. Необходимо чтобы функция не опиралась на ссылочное сравнение, не опиралась на поведение и состояние и работала для любых типов.
S>>>Ты не можешь доказать физическую идентичность. Следовательно ее нет? G>>Ок, давай выяснять что такое физическая идентичность. Покажи чем физическая идентичность отличается от ссылки? Напомню что в прошлом посте ты показал эквивалентность этих понятий. S>Они отличаются определением.
Определения у тебя неформальны, ты не можешь доказать что между ними какая-то разница есть
S>>>>>Это ссылочная эквивалентность а не идентичность. Из нее следует физическая идентичность. Из физической идентичности следует ссылочная эквивалентность. Но это не одно и то же. Понятия разные, но наблюдаются они у объекта одновременно. Смотри определения. G>>>> G>>>>Если A -> B && B -> A, то A == B, это формальная логика, можешь с ней не спорить. S>>>Нет такой логики. Есть такая: S>>>A => B && B => A, то A <=> B (читается тогда и только тогда) не путай их. Не делает чести. G>>
G>>Ты привел одно и тоже заменив -> на => и == на <=>. G>>http://www.ctc.msiu.ru/materials/Book2/ch_07_sheets/01_logic/03_implies/
G>>
G>>Другой распространенной операцией является эквивалентность. Ее аналог в разговорной речи — фразы, подобные словосочетанию тогда и только тогда, когда ... или если и только если ... Для ее обозначения используется символ <-> или просто =.
S>То что ты мне привел — это эквивалентность между высказываниями или формулами, когда они принимают одни и те же истинностные значения. Из эквивалентности высказываний не следует эквивалентность понятий, заданными разными определениями.
Очень даже следует потому что булева логика работает для предикатов любой природы. Этому на первом курсе любого технического вуза учат.
S>Ты же мне написал что физическая идентичность эквивалентна равеству ссылок, а потом поставил знак ==.
По тому что ты написал это так и есть. G>>На википедии кстати статьи про логическую эквивалентность нет, надо что-то кроме википедии читать S>выбирай, что читать.
Не надо выбирать, надо все читать
S>Следствие в википедии говорит об объектах одного типа.
Оно говорит глупость, которая опровергается банальным сравнением ссылок.
S>>>Только как ты не можешь доказать физическую идентичность объекта самому себе, так и я не смогу доказать логическую идентичность a и b. G>>Видимо ты не те определения выбрал что не можешь доказать что-то из них. S>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
Его не надо доказывать, в спецификации языка написано что ссылка есть identity.
S>>>Тем не менее, я их считаю их идентичными согласно определению. G>>Согласно определению они как раз неидентичны, потому что я тебе легко приведу выражение отличающее их друг от друга (угадай какое). S>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности.
Да, в определении есть функция id(object), которая id(a)==id(b) только когда a и b совпадают. Но как это реализовать не имея сравниваемых ссылок? Во всех известных мне реализациях используются ссылки для идентичности. Ты не можешь доказать что возможна идентичность без ссылок.
S>>>Что будешь делать если ссылки сравнить нельзя, либо как подметил Ikemefula, если две неравные ссылки ссылаются на один объект и из неравенства ссылок не следует неидентичность? G>>Приведи язык где нельзя сравнить ссылки? Если ссылки не одинаковы в битовом представлении, то есть инвариантный формат, их надо привести и сравнить. S>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет.
И как ты функцию id(object), которая id(a)==id(b) только когда a и b совпадают. Которая работает для любого типа, приведи код.
G>>Для простоты давай называть ссылкой инвариантый формат, чтобы не усложнять рассуждения. S>Незачем. Тебе C# позволяет привести ссылку к инвариантному формату?
Она уже в инвариантном формате.
G>>>>Одним написанием определений ты ничего не докажешь. Нужен код. S>>>Ты не написал код, убеждающий в идентичности объекта самому себе строго G>>object.ReferenceEquals(a,a) не? ведь ссылка работает как identity, тебе не удалось этого опровергнуть. S>Тебе не удалось это доказать.
Это в спецификации написано, Синклер приводил
G>>>>Идентичность и позволяет отличить объект от других, то есть id(a) == id(b) только когда a и b это один и тот же объект. S>>>Это выдумка, которая не следует из определения идентичности. В частности в определении не упоминается "один и тот же". G>>Да, там упоминается "отличить от других". Давай пререфразирую, id(a) != id(b) только когда a и b — разные объекты. Опять-таки формальная логика рулит, я просто сделал отрицание обеих частей выражения, таблица истинности не поменялась. S>Не рулит логика, когда неверен посыл. Докажи что разные объекты а и b будут иметь различные if(a) и id(b). Формально из определения, пожалуйста, а не руководствуясь домыслами о равенстве ссылок.
object identity — identity is that property of an object that distinguishes each object from all others
Значит существует функция id(object), которая id(a)!=id(b) только когда a и b разные объекты. Соответственно когда они одинаковые объекты, то совпадают.
S>>>Мне необязательно доказывать тебе возможность существования другой реализации конкретным примером. Хотя ключ я уже дал. Представь себе ООП систему, где невозможно сравнение ссылок либо убеди себя что такой не может существовать. G>>Ок, представим. Как ты в такой системе обеспечишь identity? Как ты напишешь выражение, которое позволяет отличить один объект от другого? S>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity.
object identity — identity is that property of an object that distinguishes each object from all others
Выделенное слово означат различать.
G>>>>Так приведи код, который проверит "логическую идентичность". S>>>Приведи код, который проверит физическую идентичность формально, а не по ReferenceEquals. G>>Давай начнем с определения "физической идентичности", что это такое? Как оно выражается в языке? S>Определение то же самое. Выражения в языке нет. ReferenceEquals выражает равенство ссылок а не идентичность. Покажи что не найдется свойства, по которым можно отличить объект от самого себя. Кодом!
Это написано в спецификации языка. Более того, даже если не написано то по всем наблюдаемым признакам ссылка ведет себя как identity — походит под все
определения и реализует все свойства.
G>>>>В соответствии с высказыванием ты утверждаешь что бывает так что Object.ReferenceEquals(a,b) == false, но это один и тот же объект. S>>>Я такого не утвреждаю. G>>А что тогда утверждаешь? только кодом. S>Я утверждаю что из неравенства ссылок может следовать same identity.
Приведи пример, функция id(object), которая id(a)==id(b), но a!=b. При этом работает для любых типов, не опирается на состояние и поведение объекта.
S>Кодом я identity записать не могу. Да и ты пока не смог.
Еще раз: по спецификации ссылка и есть identity, а даже если не так, то по всем наблюдаемым признакам ссылка ведет себя как identity.
G>>>>Приведи пример языка где инвариантные ссылки не совпадают, но это один и тот же объект. S>>>Это не обязательно. Я рассуждаю о концептуальной модели, а не о частной ее реализации. G>>Рассуждать можно о чем угодно, даже том чего не существует. В программировании легко провести эксперимент, он не требует ничего кроме умственных усилий и немного времени. Покажи пример того о чем ты пытаешься рассуждать. S>См. пример с monostate.
Там нет идентичности, я банально могу различить эти два объекта. При same identity это было бы невозможно.
G>>Я говорю что во всех практических реализациях есть ссылки на объекты (инвариантные ссылки если угодно), которые как раз выполняют роль identity. При этом сами ссылки могут не совпадать (COM), но приводятся к инварианту, которые совпадают для одинаковых объектов, также ссылки могут иметь непостоянное битовое представление (.NET и Java). Могут быть сложными значениями — ключи строк в БД. S>Я говорю об концептуальной модели а не о практических реализациях.
Приведи реализацию idenity без ссылок.
G>>Ты же понамешал сюда логическую и физическую идентичность, при этом не можешь дать определение ни одной, ни другой. G>>Это и есть демагогия. S>Я давал. Еще раз. Физическая идентичность — идентичность основанная на равенстве ссылок/адресов/хэндлов/уникальных системных идентификаторов. Хочется назвать ее суррогатной идентичностью, т.к. ссылки и т.п. не имеют отношения к объекту, его состоянию и поведению. Логическая идентичность — идентичность, которая основывается на наблюдаемом поведении объекта. И да, я знаю что поведение и состояние не влияют на идентичность. Потому предлагается устанавливать идентичность по разнице в наблюдаемом поведении.
Значит физическая идентичность — равенство ссылок. Или как еще понимать "основанная на"? А логическая идентичность — не идентичность вообще, потому что не соответствует определению отсюда.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, samius, Вы писали: S>>Что такое эквивалентность в смысле дотнетного стандарта? В ECMA-355 нет самостоятельного определения экивалентности, только упоминание ее в различных контекстах. S>Вы опять как-то альтернативно читаете? Та же самая секция 8.2.5, подсекция 8.2.5.2 Equality.
Да, подсекция equality вводит отношение эквивалентности. Но я искал "equivalent"
S>>структурная эквивалентность в смысле побитового совпадения областей памяти? Я пытался ввести эквивалентность поведения, что очевидно не то же самое, что структурная эквивалентность. S> Тогда ваше определение не совпадает даже с тем единственным местом, где хоть кто-то кроме вас вводит понятие логической идентичности.
Не совпадает. Но некоторые объекты (например, неизменяемые) могут удовлетворить и моей и той версии со структурной эквивалентностью. Хотя они и не обязаны быть эквивалентными структурно.
Предлагаю на этом паузу. Будет время и силы (не сегодня — завтра) я внимательно пробегусь по определениям, попытаюсь переосмыслить, постараюсь не наделать глупостей и обещаю отписать о результатах.
Здравствуйте, samius, Вы писали:
S>>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки. S>выполняет роль, но не является.
С точки зрения математики, "выполнять роль" и "являться" — одно и то же.
Если вы собираетесь переопределять значение термина "являться", то увольте меня от дальнейшей беседы. Ибо шизофрения — дивный мир, но я в него не вхож.
S>>Если бы следствие в википедии являлось действительно следствием, то его можно было бы формально доказать, исходя из определения там же. Увы. S>Верно. Тем более, в исправленной форме это следствие действительно упоминается неоднократно. S>Приближаюсь к объявлению капитуляции
S>Это своя реализация идентичности. Не интересно.
Что значит "своя"? А вы хотели чужую? Идентичность — это математическое понятие. Реализация идентичности — она всегда своя.
S>Для конкретной реализации — да.
А в общем случае они и не применимы. S>Да, для ECMA понятия идентичности это верно. Но обобщить до определения идентичности в ООП это нельзя.
Это верно.
S>Компилировать FCL в C#-- не надо, нет такой цели
А в чём цель? Я думал, вы хотите получить работоспособную ОО-модель. S>Имеет смысл если ID вычислима. Но я не говорил что она вычислима.
Если она невычислима, то у нас нет "способа отличать один объект от любого другого объекта". Упс. S>В той трактовке, что позволяет отличать любой объект от всех остальных — да.
Это не трактовка, это само определение.
S>Ну дак мы их отличать можем в теории, по некой невычислимой функции. Существования такой функции достаточно, вычислимость ее — это просто очень полезный бонус
Хм. Тут мои познания в computer science заканчиваются. Остаётся только смутное сомнение в
а) существовании невычислимых функций (чем оно отличается от несуществования такой функции?)
б) в применимости невычислимых функций в определениях моделей, применяемых для прикладного программирования. Мне кажется, что во всех местах, когда говорят "свойство того-то" или "функция от того-то", то везде неявно продразумевают "вычислимая детерминированная".
S>мы можем отличать объекты с отличным поведением (но только их). Отличать объекты с неотличимым поведением не нужно. Но это уже видимо моя додумка.
Да, это ваша додумка.
S>Про "следовать" погорячился. можем одновременно наблюдать неравенство ссылок и same identity.
Это правда, и это явно описано в википедии, хотя и не обосновано формально. S>Вот по этим изменениям я и предлагал определять идентичность.
Такая идентичность не будет сохраняться.
Поясню примером:
public class NonIdentic
{
public int A { get; set; }
}
...
var a = new NonIdentic();
var b = new NonIdentic();
(для упрощения предположим, что никаких других методов, кроме явно объявленных, у нас нет)
Вот у нас два экземпляра. Что такое их поведение? Это их реакция на сообщения. Сообщений экземпляру мы можем послать всего два. Пошлём им getA():
var r1 = a.A; var r2 = b.A;
Debug.Assert(r1 == r2);
Так, поведение одинаково.
Пошлём setA():
a.A = 1; b.A = 1;
var r1 = a.A; var r2 = b.A;
Debug.Assert(r1 == r2);
Опять то же самое. Какую бы цепочку сообщений getA/setA мы ни придумали, цепочка ответов от объектов a и b будет совершенно одинаковой. То есть их поведение — одинаково. Значит, у них должна быть одинаковая "логическая identity".
Однако, стоит нам сделать хоть что-то несимметричное, как их поведение тут же станет различным. Упс.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, samius, Вы писали:
S>Да, подсекция equality вводит отношение эквивалентности. Но я искал "equivalent"
equivalence
S>Не совпадает. Но некоторые объекты (например, неизменяемые) могут удовлетворить и моей и той версии со структурной эквивалентностью. Хотя они и не обязаны быть эквивалентными структурно.
Ну а зачем нам такое определение идентичности, которое работает не для всех объектов?
Я не против его как отношения эквивалентности. Возможных отношений эквивалентности для объектов очень много. Отношение идентичности выделяется среди всех них особым свойством — оно вводит ровно столько классов эквивалентности, сколько у нас есть экземпляров объектов.
S>Предлагаю на этом паузу. Будет время и силы (не сегодня — завтра) я внимательно пробегусь по определениям, попытаюсь переосмыслить, постараюсь не наделать глупостей и обещаю отписать о результатах.
Ок. Я тоже уже сильно отстал от графика работ
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
Необходимым является само наличие ссылок (или чего-то, выполняющее их функцию). Функцией ссылки является обеспечение возможности обращения (вызова метода, посылки сообщения и т.п.) к конкретному объекту.
Кроме того, нужна возможность разным ссылкам ссылаться на один и тот же объект. "Один и тот же объект" означает, что вызовы его методов и изменения его состояния через любую из ссылок, на него ссылающихся, абсолютно эквивалентны.
И эти гарантии должны обеспечиваться языком программирования.
Вот если выкинуть, например, из C++ указатели и ссылки, а любые "объекты" передавать по значению — ООП будет невозможен:
A a1 = ...;
a1.setValue(0);//1
a1.setValue(42);//2
A a2 = a1;
a2.setValue(13);
assert(a1.getValue() == a2.getValue());//упс
Хитрость еще в том, что даже тут идентификаторы a1 и a2, по сути, все еще являются ссылками. В строках //1 и //2 мы работаем все с тем же объектом. Только в языках с полным отсутствием изменяемого состояния возможно, чтобы идентификатор не был ссылкой.
Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
S>Здравствуйте, samius, Вы писали:
S>>Мы говорим про ООП а не про БД. Для ООП ссылка не нужна. Об этом нигде не написано. Требуется механизм посылки сообщения с точностью до identity. Это можно обеспечить идентификатором. S>Если это можно обеспечить идентификатором, то идентификатор выполняет роль ссылки. По определению ссылки.
+1
S>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет. S>Смешные упражнения. Ок, пусть у нас будет ООП-система, в которой ссылки сравнивать нельзя — из неравенства ссылок не следует ничего интересного. Отлично, чтобы отличать объекты друг от друга, мы запихаем внутрь каждого экземпляра GUID. S>0. Этот GUID будет волшебным образом генерироваться при всяком создании объекта, будь то "с нуля" или при клонировании объекта. S>1. Этот ID будет недоступен коду самого объекта; его будет невозможно изменить в течение всего времени жизни. S>2. Сделаем волшебную функцию ID(obj), которая будет залезать внутрь объекта и возвращать его GUID. S>3. Объект никак не сможет повлиять на реализацию этой функции. S>Введённая нами функция ID удовлетворяет определению идентичности: она одинаковая для одного и того же объекта; она разная для разных объектов в силу 0; она не зависит от состояния объекта в силу 1; она не зависит от поведения объекта в силу 3.
Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. Не зависимо от того, как реализовано клонирование\копирование — с назначением нового ID или использованием того же.
Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа).
S>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>Не надо путать определение идентичности и реализацию идентичности. S>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода.
+1
А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
S>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает.
Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
S>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений.
Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны.
Операции сравнения, как элемента языка, не требуется.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
A>Пять копеек.
Это червонец, не меньше
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. A>Необходимым является само наличие ссылок (или чего-то, выполняющее их функцию). Функцией ссылки является обеспечение возможности обращения (вызова метода, посылки сообщения и т.п.) к конкретному объекту. A>Кроме того, нужна возможность разным ссылкам ссылаться на один и тот же объект. "Один и тот же объект" означает, что вызовы его методов и изменения его состояния через любую из ссылок, на него ссылающихся, абсолютно эквивалентны.
Более того, мы можем потребовать от реализации идентичности не создавать различные экземпляры объекта, чьи поведения будут неотличимы. Незачем. Тогда понятия "один и тот же объект" и неотличимость поведения будут следовать друг из друга. Как это будет расположено в памяти — никого не должно волновать, т.к. объекты будут формально отличаться по поведению, а не по location-у. Если объект невозможно изменить, он будет "синглтоном". Если можно — то как обычно. И то что его можно будет изменить отдельно от других объектов, определяет его идентичность.
Такая модель реализации будет соответствовать определению идентичности более чем вполне вместе с требованиями независимости ID от состояния и поведения объекта. Практическая ценность такой модели совершенно не интересует. Интересует принципиальная возможность существование идентичности в ООП, отличной от определяющейся через location и равенство ссылок.
В такой модели равенство ссылок все равно будет приводить к идентичности. Но определять равенство ссылок не требуется, а значит его можно опустить
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
S>>>Я помню что ты считаешь ссылку на объект свойством объекта. Только в определении об этом почему-то не написано. Так что твое выражение отличающее ссылки не будет иметь прямого отношения к определению идентичности. S>>Не надо путать определение идентичности и реализацию идентичности. S>>Применимость ссылок для идентичности в дотнете нетрудно доказать в два хода. A>+1 A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
идентичность в дотнете определена через locations, что является более сильной моделью, чем идентичность ООП.
S>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
+1
S>>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений. A>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>Операции сравнения, как элемента языка, не требуется.
И я об этом.
Здравствуйте, artelk, Вы писали:
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве.
К примеру, я знаю, что стандартные коллекции сразу же перестанут работать.
Можно ли будет их чем-нибудь заменить, я не в курсе.
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются?
Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
A>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован.
Почему? В вашей фразе если ... и то ... никак не связаны между собой.
Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
A>Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа).
Ничего не понял, извините.
A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
Я же только что показал, как реализовать идентичность без использования ссылок. Нет, идентичность и ссылки друг из друга в общем случае не выводятся.
A>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>Операции сравнения, как элемента языка, не требуется.
Можно пояснить,что вы понимаете под "гарантировать тождественность"?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
A>Пять копеек.
A>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно.
А как тогда узнать что пара объектов — один и тот же? Ведь на эту операцию завязано много чего.
A>Вот если выкинуть, например, из C++ указатели и ссылки, а любые "объекты" передавать по значению — ООП будет невозможен: A>
A>Хитрость еще в том, что даже тут идентификаторы a1 и a2, по сути, все еще являются ссылками. В строках //1 и //2 мы работаем все с тем же объектом. Только в языках с полным отсутствием изменяемого состояния возможно, чтобы идентификатор не был ссылкой.
Это неправда. Несмотря на синтаксическую конструкцию A a2 = a1, которая выглядит как присваивание, выполняется конструктор копирования. Что недвусмысленно говорит о копии объекта. но никак не том же самом объекте.
A>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а).
Покажи пример такого.
A>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. Не зависимо от того, как реализовано клонирование\копирование — с назначением нового ID или использованием того же.
Почему? Докажи.
A>А я даже не представляю как реализовать идентичность без использования ссылок... Оба понятия друг из друга выводятся, имхо.
Ну да, ибо идентичность это функция вида ID(object), подчиняющаяся некоторым правилам. Если получить битовое представление результата этой функции, то его можно назвать "ссылкой". Другое дело что необязательно для каждой ссылки можно получить некоторый объект.
S>>>Незачем приводить язык без ссылок. Но если хочется — можно пофантазировать. Пусть будет C#--, который будет в точности C#, но без возможности сравнения ссылок. Обращаться по ссылке можно, сравнивать — нет. S>>Вполне возможный язык. Ну, для начала в таком C#-- не скомпилируется FCL. S>>Чтобы она скомпилировалась, придётся придумать способ обойти это ограничение, потому что на сравнении идентичности объектов основано довольно много кода. Если мы не придумаем способ сделать IsIdentic(ref1, ref2), то дотнет так и не заработает. A>Равенство ссылок C# — более сильное условие, чем необходимо в ООП для определения идентичности.
В чем? Покажешь пример равенства ссылок без идентичности?
S>>>ООП не требует возможности отличать объекты, ООП требует доставки сообщений объекту с некоторой identity. S>>Первым делом ООП требует возможности отличать. Это определение identity. Уже потом оно требует доставки сообщений. A>Первым делом ООП требует возможность гарантировать тождественность.
Тождественность — и есть совпадение identity в ООП.
A>Операции сравнения, как элемента языка, не требуется.
С учетом сказанного выше — требуется.
Здравствуйте, Sinclair, Вы писали:
S>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
S>А рич-модель бесплодно пытается приделать офицерской вдове метод "высечь". Или вместо того, чтобы породить экскаватор, пишет земля.копайся().
Опять же, анемик - явная ерунда, рич - непрактичная выдумка теоретиков.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, artelk, Вы писали:
A>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. S>Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве.
object.ReferenceEquals — метод из .NET Framework, а не элемент языка C#. S>К примеру, я знаю, что стандартные коллекции сразу же перестанут работать. S>Можно ли будет их чем-нибудь заменить, я не в курсе.
Заставлять реализовывать IEquatable или передавать отдельно IEqualityComparer.
A>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). S>Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются?
Метод object.ReferenceEquals, для того, чтобы вернуть true, от переданных параметрами ссылок требует большего, чем чтобы они ссылались на идентичные объекты.
Возврат true означает, что имеет место идентичность. Но идентичность объектов не является достаточным условием, чтобы результатом было true. S>Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
Смотри:
var a1 = new SomeClass(...);
//какой-то кодvar a2 = a1;
//куча произвольного кода, со множеством обращений к объекту по ссылке a1
Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному.
Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2.
interface ISomeClass
{
method1(...);
//
methodN(...);
}
class SomeClass: ISomeClass
{
method1(...){...}
//
methodN(...){...}
}
class SomeClassProxy: ISomeClass
{
private readonly ISomeClass o;
SomeClassProxy(ISomeClass o) {this.o = o;}
method1(...){ o.method1(...); }
//
methodN(...){ o.methodN(...); }
}
ISomeClass a1 = new SomeClass(...);
//какой-то код
ISomeClass a2 = new SomeClassProxy(a1);
//куча произвольного кода, со множеством обращений к объекту по ссылке a1
Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному.
Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2, хотя object.ReferenceEquals(a1, a2) вернет false.
A>>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. S>Почему? В вашей фразе если ... и то ... никак не связаны между собой. S>Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
ID id = ...;
Retrieve(id).SomeMethod1();//1
Retrieve(id).SomeMethod2();//2
Если бы конструкция "Retrieve(???)." была элементом языка, то она была бы эквивалентна вызову через точку "???." (просто другой синтаксис), поэтому этот ID являлся бы ссылкой (смысл тот же)...
Если это метод — то нужно определить, что означает "возвращать нужный нам объект". В //1 и //2 мы работаем с тем же объектом? Retrieve возвращает что-то, через что можно обратиться к конкретному объекту? Так это ссылка. Т.е. ссылки уже должны поддерживаться языком.
Ок, по порядку.
samius>>Выбери определение идентичности и докажи кодом идентичность объекта самому себе, не опираясь на ссылки, упоминания о которых, надеюсь в твоем определении не будет.
var z = new Something(...);//генерируется уникальный ID
assert(ID(z) == ID(z));//z - ссылка!
В языке уже должны быть реализованы ссылки, чтобы ID мог бы быть использован для определения identity.
И Something должен быть ссылочным типом (классом).
Если он структура, то в ID передается копия. А копия, по твоей версии, имеет свой уникальный ID.
Второй случай (думаю, ты его имел ввиду), ссылок почти нет:
struct Something
{
public readonly ID id;
public Something()
{
id = ID.GetUniqueId();
}
//Копирование работает обычно, т.е. id копируетсяpublic int State {get;set;}
public Something Clone(){...}
}
var z1 = new Something(...);
z1.State = 1;//1var z2 = z1;//id копируется, значит должны быть идентичны
z2.State = 2;//2
assert(ID(z1) == ID(z2));//true
assert(z1.State == z2.State);//false, как же так?
Ссылки все еще есть, т.к. когда в строчках //1 и //2 мы обращаемся к z1 и z2, последние выступают в роли ссылок.
"z1.State = 1;" — мы обращаемся к тому же "объекту", что только что создали. При отсутствии копирования, структуры сохраняют свою идентичность.
Третий случай:
struct Something
{
public readonly ID id;
public Something()
{
id = ID.GetUniqueId();
//INSERT INTO table (ID, State) VALUES ($id, 0)
}
//Копирование работает обычно, т.е. id копируетсяpublic int State
{
get { //SELECT State FROM table WHERE ID = $id }set { //UPDATE table SET State=$value WHERE ID = $id }
}
public Something Clone(){...}
}
var z1 = new Something(...);
z1.State = 1;//даже если бы обращались к копии структурыvar z2 = z1;//id копируется, значит должны быть идентичны
z2.State = 2;//даже если бы обращались к копии структуры
assert(ID(z1) == ID(z2));//true
assert(z1.State == z2.State);//true!
Более того, ID может работать как ссылка (при наличие Retrieve):
Причем Retrieve может быть как элементом языка, так и функцией, возвращающей копию структуры.
A>>Исключением является, например, случай, если ID копируется, а объект хранит свое состояние где-то вовне и "копии" разделяют это состояние (например, Active Record, каждый раз обращающийся к базе для получения\сохранения своего состояния с использованием ID в качестве ключа). S>Ничего не понял, извините.
Я имел ввиду третий случай.
S>Нет, идентичность и ссылки друг из друга в общем случае не выводятся.
Как-то так:
Сослаться можно только на то, что обладает идентичностью.
Идентичность — возможность сослаться на конкретный объект.
A>>Первым делом ООП требует возможность гарантировать тождественность. С# предоставляет реализацию ссылок с обеспечением гарантий их равенства при присвоении одной ссылки другой и при передаче ее как параметра метода, а также гарантируется, что, при равенстве ссылок, объекты, на которых они ссылаются, идентичны. A>>Операции сравнения, как элемента языка, не требуется. S>Можно пояснить,что вы понимаете под "гарантировать тождественность"?
var a1 = new SomeClass(...);
var a2 = a1;
a2.Method();//тождественно a1.Method()
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, Sinclair, Вы писали:
S>>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
ANS>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
Здравствуйте, artelk, Вы писали:
A>Здравствуйте, Sinclair, Вы писали:
S>>Здравствуйте, artelk, Вы писали:
A>>>Все же, наличие операции сравнения ссылок для определения идентичности не является необходимым для того, чтобы на конкретном языке программирования можно было писать в ООП стиле. Если из .NET/C# выкинуть object.ReferenceEquals, то разрабатывать в ООП стиле все еще будет возможно. S>>Вот это утверждение, на мой взгляд, является весьма сильным, и нуждается в доказательстве. A>object.ReferenceEquals — метод из .NET Framework, а не элемент языка C#.
По секрету
var a = new object();
var b = new object();
Debug.Assert(a == b)
Посмотри в IL во что оператор сравнения компилируется
S>>К примеру, я знаю, что стандартные коллекции сразу же перестанут работать. S>>Можно ли будет их чем-нибудь заменить, я не в курсе. A>Заставлять реализовывать IEquatable или передавать отдельно IEqualityComparer.
Тебя слово Equality не смущает? Оно недвусмысленно говорит об эквивалентности, а не об идентичности. Прочитай посты где были приведены ссылки на стандарт.
A>>>Что касается object.ReferenceEquals, то, если он возвращает true, то ссылки гарантированно ссылаются на "один и тот же объект". Однако он может и вернуть false для ссылок на идентичные объекты. Т.е. он накладывает более сильные требования к ссылкам, чем этого требуется для обеспечения идентичности, необходимой для возможности писать в ООП стиле (aka "логической идентичности" в терминологии samius-а). S>>Не понял, кто накладывает "более сильные требования", и какие именно требования накладываются? A>Метод object.ReferenceEquals, для того, чтобы вернуть true, от переданных параметрами ссылок требует большего, чем чтобы они ссылались на идентичные объекты. A>Возврат true означает, что имеет место идентичность. Но идентичность объектов не является достаточным условием, чтобы результатом было true.
Ок, покажи пример когда object.ReferenceEquals возвращает true для разных объектов.
S>>Опять же — оператор может вернуть false, оставаясь в рамках ECMA? По-моему, это неправда
A>Если в этой "куче кода" в любых местах заменить обращение к a1 на обращение к a2, то поведение программы будет эквивалентно исходному. A>Т.е. объект, на который ссылается a1 идентичен объекту, на который ссылается a2.
Путаешь эквивалентность и идентичность. Эквивалентность — любое симметричное, рефлексивное и транзитивное отношение, идентичность двух объектов — такое отношение в котором объект эквивалентен только сам себе, при это отношение не опирается на состояние и поведение объекта.
A>>>Если при конструировании объекта "с нуля" ему назначается уникальный ID, то, в общем случае, как ссылка он не сможет быть использован. S>>Почему? В вашей фразе если ... и то ... никак не связаны между собой. S>>Для возможности использовать ID в качестве ссылки необходимо и достаточно иметь некоторую функцию Retrieve(GUID id), которая будет возвращать нужный нам объект. Но я про это ничего не писал и не предлагал использовать ID в качестве ссылки. Я предлагал использовать его в качестве identity.
A>Второй случай (думаю, ты его имел ввиду), ссылок почти нет: A>
A>struct Something
A>{
A> public readonly ID id;
A> public Something()
A> {
A> id = ID.GetUniqueId();
A> }
A> //Копирование работает обычно, т.е. id копируется
A> public int State {get;set;}
A> public Something Clone(){...}
A>}
A>var z1 = new Something(...);
A>z1.State = 1;//1
A>var z2 = z1;//id копируется, значит должны быть идентичны
A>z2.State = 2;//2
A>assert(ID(z1) == ID(z2));//true
A>assert(z1.State == z2.State);//false, как же так?
A>
A>Ссылки все еще есть, т.к. когда в строчках //1 и //2 мы обращаемся к z1 и z2, последние выступают в роли ссылок. A>"z1.State = 1;" — мы обращаемся к тому же "объекту", что только что создали. При отсутствии копирования, структуры сохраняют свою идентичность.
Ага, потому что value типы в CLR не соответствуют ООП. Мы тут рассматриваем только reference-типы.
S>>Нет, идентичность и ссылки друг из друга в общем случае не выводятся. A>Как-то так: A>Сослаться можно только на то, что обладает идентичностью. A>Идентичность — возможность сослаться на конкретный объект.
Нет, определение не говорит нам о возможности "сослаться", то есть об операции dereferencig. Но без нее реализация скорее всего невозможна. Хотя могут быть случаи что не всегда можно сделать dereferencig.
Здравствуйте, gandjustas, Вы писали:
S>>>Чтобы понять, почему анемик не является менее ООП, достаточно отойти чуть назад и задуматься.
ANS>>Это зависит от трактовки дефиниций. Если посмотреть на изначальную трактовку, то это явно не ООП.
G>Ага, фаулер говорит что anemic — не ООП, и все сразу верят.
Ну, я как бы, думал, что ты что-то своё под этим понимаешь. Я тут у многих заметил склонность к изобретению своих трактовок терминов и их ниспровержению. То примитивный мапер лёгким ОРМ обзовут, то еще что. Даже ссылку дал, дабы прояснить горизонты. И любому здравомыслящему человеку сразу видно, что описанное по ссылке не ОО-подход