Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Практичная теория

3 views
Skip to first unread message

Anton Moscal

unread,
Mar 15, 2004, 2:03:15 PM3/15/04
to
Fri Mar 05 2004 19:48, Dmitry Sidoroff wrote to All:


DS> Объект и операция идентичности.
DS> Hазовем объектом нечто, что идентичное себе и только себе.
DS> Операция идентичности это не то же самое, что операция равенства. Разные
DS> (не идентичные) объекты могут быть равны. Идентичные объекты, как
DS> правило, равны.

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

Идентичные объекты imho всегда равны.

DS> Задание точного типа связи не имеет смысла с точки зрения теории
DS> поскольку, во-первых интерфейсы это единственное средство задать общий
DS> набор свойств объекта, во вторых в языке тип реализации может
DS> отсутствовать.

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

DS> Объект существует после окончания операции его создания и до окончания
DS> операции его удаления. В языках со сборкой мусора удаление объекта
DS> инициируется сборщиком мусора.

В языках со сборкой мусора подразумевается, что все объекты существуют вечно,
а сборка мусора - это всего лишь оптимизация. Финализаторы - это
низкоуровневый хак для частных случаев, когда объект связан с каким-то
ресурсом (файлом, областью в С-шной куче etc), за пределами компетенции
сборщика мусора, который тоже неплохо бы отдать, когда станет не нужен.

Любое другое использование финализатора категорически не поощряется.

DS> объектами кроме метаобъектов потому что порядок удаления объектов не
DS> предсказуем и обращения будут происходить к уже удаленным объектам.

В финализаторе не может быть обращений к уже удаленным объектам. Финализаторы
вызываются _до_ освобждения соотвествующих.

Антон Москаль

Dmitry Sidoroff

unread,
Mar 17, 2004, 11:05:07 AM3/17/04
to
Привет Anton!

15 Мар 04 22:03, Anton Moscal -> Dmitry Sidoroff:

DS>> Объект и операция идентичности.
DS>> Hазовем объектом нечто, что идентичное себе и только себе.
DS>> Операция идентичности это не то же самое, что операция равенства.

DS>> Разные (не идентичные) объекты могут быть равны. Идентичные
DS>> объекты, как правило, равны.
AM> Традиционная трактовка такая - объекты идентичны, если не существует
AM> возможности их различить.
Это либо глюк либо необъектные языки. В общем случае два равных объекта не тоже
самое что две ссылки на один и тот же объект. Доказательство тривиально, а.m =
1; б.m = 2; а.m==б.m не одинаково.

Оптимизацию тут и ниже я не трогаю. Это тема длиная. В отличии от должна быть
куча оптимизии на уровне языковых конструкций.

AM> При наличии операции сравнения указателей они идентичны только если
AM> это физически один и тот же объект,
Hу да, сейчас как операция идентичности чаще всего используется сравнение
адресов.
AM> иначе - различные объекты могут быть идентичны, если не содержат
AM> видимого пользователю изменяемого состояния (потому что тогда можно
AM> поменять состояние одного объекта и посмотреть - отразится ли на
AM> другом - всякие кэширования однако тут могут быть не заметны для
AM> юзера).
Верно, но есть еще одно условие: операция идентичности не используется.

AM> Идентичные объекты imho всегда равны.
При корректной реализации сравнения. Придумать ситуацию когда идентичные должны
быть не равны я не сумел. Hо требовать равенства нельзя хотя бы потому что
операции сравнения может и не быть.

DS>> Задание точного типа связи не имеет смысла с точки зрения теории
DS>> поскольку, во-первых интерфейсы это единственное средство задать

DS>> общий набор свойств объекта, во вторых в языке тип реализации
DS>> может отсутствовать.
AM> Замечание - схема Жабы, где объект долже явно заимплементить
AM> интерфейс вовсе не обязательна - есть статические языки, где
AM> реализует ли объект интерфейс определяется просто по факту наличия в
AM> нем нужных свойств.
Я знаю, тут проблема в однозначной идентификации свойства. Предлагается
использовать как однозначный идендентификатор, не название метода, а модуль +
интерфейс первоначального объявления + метод.

Практика показывает что просто название не катит, слишком много дублирующихся
имен и конфликты трудно разрешимы.

DS>> Объект существует после окончания операции его создания и до

DS>> окончания операции его удаления. В языках со сборкой мусора
DS>> удаление объекта инициируется сборщиком мусора.
AM> В языках со сборкой мусора подразумевается, что все объекты
AM> существуют вечно, а сборка мусора - это всего лишь оптимизация.
AM> Финализаторы - это низкоуровневый хак для частных случаев, когда
AM> объект связан с каким-то ресурсом (файлом, областью в С-шной куче
AM> etc), за пределами компетенции сборщика мусора, который тоже неплохо
AM> бы отдать, когда станет не нужен.
Дырявая миска уже дуршлаг ;-) Если объект удаляется, то он уже не вечен.
Да и эти случаи отнють не частные, загрузка из файлов или БД, сетевые передачи
и тд встречаются _очень_ часто.

По этому объект существует именно от конструктора до деструктора.
Пустой ли деструктор и кто его вызывает не принципиально.

DS>> объектами кроме метаобъектов потому что порядок удаления объектов

DS>> не предсказуем и обращения будут происходить к уже удаленным
DS>> объектам.
AM> В финализаторе не может быть обращений к уже удаленным объектам.
AM> Финализаторы вызываются _до_ освобждения соотвествующих.
Ошибка в том, что порядок вызова деструкторов важен.
Грабля известная, без агрегации невозможно написать например write-кэшер.

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

Что бы связь связь А->Б можно было использовать в деструкторе, деструктор А
должен вызыватся _до_ деструктора Б. Что и гарантирует агрегация.

Dmitry

Dmitry Sidoroff

unread,
Mar 17, 2004, 11:08:17 AM3/17/04
to
Привет Anton!

15 Мар 04 22:03, Anton Moscal -> Dmitry Sidoroff:

DS>> Hазовем объектом нечто, что идентичное себе и только себе.


DS>> Операция идентичности это не то же самое, что операция равенства.

AM> Традиционная трактовка такая - объекты идентичны, если не существует
AM> возможности их различить.

В догонку. Вспомнил я откуда тут ноги растут. В анализе действительно имеет
место быть. Бритва Оккама для замкнутого мира.

Hо этот тезис о всей модели _в_ _целом_ и ты перенося его на объект потерял
связи указывающие _на_ этот объект.

Забавно что отсюда же следует тождественость равенства и идентичности в чистом
ФП.

Dmitry

Anton Moscal

unread,
Mar 23, 2004, 7:22:23 AM3/23/04
to
Wed Mar 17 2004 19:05, Dmitry Sidoroff wrote to Anton Moscal:

AM>> Традиционная трактовка такая - объекты идентичны, если не существует
AM>> возможности их различить.

DS> Это либо глюк либо необъектные языки. В общем случае два равных объекта
DS> не тоже самое что две ссылки на один и тот же объект. Доказательство
DS> тривиально, а.m = 1; б.m = 2; а.m==б.m не одинаково.

Если поля инкапсулированы, а объект immutable by design - так сделать не
получится. О том и речь. У меня, кстати, в программах таких объектов
большинство.

AM>> При наличии операции сравнения указателей они идентичны только если
AM>> это физически один и тот же объект,

DS> Hу да, сейчас как операция идентичности чаще всего используется сравнение
DS> адресов.

Ее, вообще говоря, тоже может не быть.

AM>> объект связан с каким-то ресурсом (файлом, областью в С-шной куче
AM>> etc), за пределами компетенции сборщика мусора, который тоже неплохо
AM>> бы отдать, когда станет не нужен.

DS> Дырявая миска уже дуршлаг ;-) Если объект удаляется, то он уже не вечен.
DS> Да и эти случаи отнють не частные, загрузка из файлов или БД, сетевые
DS> передачи и тд встречаются _очень_ часто.

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

А финализатор нужен, когда неизменяемый файл хочется "прозрачно" представить
как строку или там еще чего - так что пользователю не надо знать о его
природе.

И подразумеваемая семантика объекта в языках с GC - именно вечная жизнь. А
если тебе нужно в его поведении иметь операцию убиения - она делается так же
как и любой другой метод. Я предлагаю не спорить об этом - это не
"правильно/не правильно" - это просто общепринятый дизайн такой.

Можно (и может быть - полезно) вставить в Java деструкторы, но это будет
совсем другая конструкция и необходимости в финализаторе она не снимет.

AM>> В финализаторе не может быть обращений к уже удаленным объектам.
AM>> Финализаторы вызываются _до_ освобждения соотвествующих.

DS> Ошибка в том, что порядок вызова деструкторов важен.

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

Anton Moscal

Andrei N. Sobchuck

unread,
Mar 23, 2004, 9:23:52 AM3/23/04
to
Anton Moscal <m...@mail.tepkom.ru> wrote:
AM> Если поля инкапсулированы, а объект immutable by design - так сделать не
AM> получится. О том и речь. У меня, кстати, в программах таких объектов
AM> большинство.

но не все?

--
Andrei N.Sobchuck
JabberID: and...@jabber.ru. ICQ UIN: 46466235.

Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Anton Moscal

unread,
Mar 23, 2004, 9:41:59 AM3/23/04
to
Tue Mar 23 2004 17:23, Andrei N. Sobchuck wrote to "Anton Moscal":

AM>> Если поля инкапсулированы, а объект immutable by design - так сделать не
AM>> получится. О том и речь. У меня, кстати, в программах таких объектов
AM>> большинство.

ANS> но не все?

Не все, но к чему тут это?

Anton Moscal

Andrei N. Sobchuck

unread,
Mar 23, 2004, 9:59:40 AM3/23/04
to
Anton Moscal <m...@mail.tepkom.ru> wrote:
ANS>> но не все?
AM> Не все, но к чему тут это?

К вопросу о немутирующих объектах "вообще".

Dmitry Sidoroff

unread,
Mar 23, 2004, 3:47:05 PM3/23/04
to
Привет Anton!

23 Мар 04 15:22, Anton Moscal -> Dmitry Sidoroff:

DS>> В общем случае два равных объекта не тоже самое что две ссылки на
DS>> один и тот же объект. Доказательство тривиально, а.m = 1; б.m = 2;
DS>> а.m==б.m не одинаково.


AM> Если поля инкапсулированы, а объект immutable by design - так сделать

AM> не получится. О том и речь. У меня, кстати, в программах таких
AM> объектов большинство.
Hичего не понял. Что по сути разых, но равных объектов не бывает?

AM>>> При наличии операции сравнения указателей они идентичны только

AM>>> если это физически один и тот же объект,


DS>> Hу да, сейчас как операция идентичности чаще всего используется

DS>> сравнение адресов.
AM> Ее, вообще говоря, тоже может не быть.
Она обязана быть если в языке есть RW ссылки (указатели и тд).
Если их нет, то экивалентность тоже самое что сравнение.

DS>> Если объект удаляется, то он уже не вечен. Да и эти случаи отнють не
DS>> частные, загрузка из файлов или БД, сетевые передачи и тд
DS>> встречаются _очень_ часто.
AM> В этих случаях финализаторы использовать нельзя (именно из-за того,
AM> что у них не семантика деструктора) - принято делать деструктор -
AM> метод, который отдаст ресурсы и деактивирует объект (последнее не
AM> означает его удаление - оно означает, что объект будет ругаться на
AM> любую попытку что-то с ним сделать).
Стоп. Ты путаешь термины. Деструктор это метод объекта вызываемый при
прекращении его существования. Теория гласит что явно он вызван быть не может.
После отработки деструктора объекта не существует вообще и _любое_ обращение
нему так же корректно как деление на ноль.

Со сборкой мусора, да и с расперделением памяти вообще это связано слабо.
GC финализатор частный случай деструктора и сущность лишняя.

Операция удаления объекта (delete) эт совсем другое. При наличии GC именно она
хак, ибо порождает ссылки указывающие ни на что. Более того, от агрегации это
не избавляет, все равно нужно объекты пришибать в определенном порядке.

AM> Я предлагаю не спорить об этом - это не "правильно/не правильно" -
AM> это просто общепринятый дизайн такой.
Хм. Языки с недетерминированым поведением - в помойку. Hужно доказать что можно
исключить "гонки" при случайном порядоке вызова деструкторов. Hо сделать этого
не получится, мешает, например, RW кэшер объектов.

В упрощеных ОО языках эта "общепринятость" проходит только потому что агрегация
реализуется либо на ++ в библиотеках (например ADO.NET) либо частичным отказом
от GC (и за что боролись?).

Dmitry

Anton Moscal

unread,
Mar 24, 2004, 5:57:26 AM3/24/04
to
Tue Mar 23 2004 23:47, Dmitry Sidoroff wrote to Anton Moscal:

AM>> Если поля инкапсулированы, а объект immutable by design - так сделать
AM>> не получится. О том и речь. У меня, кстати, в программах таких
AM>> объектов большинство.

DS> Hичего не понял. Что по сути разых, но равных объектов не бывает?

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

DS>>> Hу да, сейчас как операция идентичности чаще всего используется
DS>>> сравнение адресов.
AM>> Ее, вообще говоря, тоже может не быть.

DS> Она обязана быть если в языке есть RW ссылки (указатели и тд).
DS> Если их нет, то экивалентность тоже самое что сравнение.

В SML есть указатели (RW), однако операции сравнения указателей, насколько я
помню, нет. И вовсе не любой объект который _физически_ представляется
указателем, представляется им там "логически" - то есть с точки зрения
программиста.

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

DS> Стоп. Ты путаешь термины. Деструктор это метод объекта вызываемый при
DS> прекращении его существования. Теория гласит что явно он вызван быть не
DS> может.

Практика гласит что может. delete - и есть вызов деструктора.

DS> Со сборкой мусора, да и с расперделением памяти вообще это связано слабо.
DS> GC финализатор частный случай деструктора и сущность лишняя.

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

DS> Операция удаления объекта (delete) эт совсем другое. При наличии GC
DS> именно она хак, ибо порождает ссылки указывающие ни на что. Более того,

Она порождает ссылки указывающие на мертвый объект. Каковой трупик однако
может продолжать существовать.

AM>> Я предлагаю не спорить об этом - это не "правильно/не правильно" -
AM>> это просто общепринятый дизайн такой.

DS> Хм. Языки с недетерминированым поведением - в помойку. Hужно доказать что
DS> можно исключить "гонки" при случайном порядоке вызова деструкторов. Hо
DS> сделать этого не получится, мешает, например, RW кэшер объектов.

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

Anton Moscal

0 new messages