Re[17]: Кто автор?
От: gbear Россия  
Дата: 05.08.05 03:18
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>>Это — ошибка. Смысл-то как раз в том, что P не должна, как Вы выразились, "понять" что ей "подпихнули" S вместо T.


G>Это — не ошибка. Я взял двойное отрицание. a == !!a. Читайте внимательнее, это одно и то же.


Действительно так. Примите мои извинения. В этом месте я был неправ.

G>> Возвращаясь к квадрату и прямоугольнику: все множество инвариантов квадрата лежит внутри множества инвариантов прямоугольника.


G>А вот это — ошибка. Инвариант квадрата: Width == Height. У прямоугольника нет такого инварианта.


Хм... Т.е. для прямоугольника, состояние когда его ширина равна высоте является не допустимым?!

G>Вот еще один инвариант квадрата: Area == Width^2 == Height^2. Для прямоугольника не выполняется. Это если говорить о геометрических фигурах.


Вообще говоря... Для квадрата понятия ширина/высота избыточны... для него оперируют другим понятием — размер стороны. И этот инвариант квадрата "укладывается" в инварианты прямогугольника, находящегося в сотоянии Width == Height. Если, конечно, допустить что такое состояние для прямоугольника является допустимым.

G>А теперь о вашем решении (последняя попытка объяснить — ничего нового я вам сказать больше не смогу): Area — инвариант метода S::get_Size (он не меняет площадь, что совершенно естественно и ожидаемо для длины ребра квадрата), но он не является инвариантом его реализации в подклассе R::get_Size. Нарушение этого инварианта будет видимо пользователю S. При этом, исключать это из спецификации S нельзя — с какой стати площадь квадрата должна меняться при попытке узнать длину стороны?


Ок. Смотрим на два черных ящика
Автор: gbear
Дата: 03.08.05
.

G>Вот и все. Вы нарушаете принцып Лисков, определение подтипа и вообще все, что можно нарушить. Постусловие метода R::get_Size получается слабее, чем в базовом классе (инвариант метода преобразуется в пару предусловие — постусловие: S::get_Size true -> Area_pred==Area_post==result^2, в то время как R::get_Size true -> Area_post == result^2).


Хорошо, хорошо... С этим согласен. Наличие такого постусловия в контракте квадрата, бесусловно, делает такой вариант невалидным. Другое дело, что этот вариант не едиственный.

---
С уважением, Сиваков Константин.
Re[18]: Кто автор?
От: Павел Кузнецов  
Дата: 05.08.05 03:38
Оценка:
gbear,

> G>> Возвращаясь к квадрату и прямоугольнику: все множество инвариантов квадрата лежит внутри множества инвариантов прямоугольника.

>
> G> А вот это — ошибка. Инвариант квадрата: Width == Height. У прямоугольника нет такого инварианта.
>
> Хм... Т.е. для прямоугольника, состояние когда его ширина равна высоте является не допустимым?!

Инвариант — ограничение, накладываемое на множество состояний, которые могут принимать объекты данного класса. У квадрата есть ограничение, заключающееся в том, что для всех объектов ширина должна равняться высоте. У прямоугольника такого ограничения (инварианта) нет.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[21]: Кто автор?
От: gbear Россия  
Дата: 05.08.05 03:55
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Т.е. одним из следствий удвоения Size является учетверение Area. Так? (*)


Хм... Хороший вопрос. Для квадрата — да. Но и для, прямоугольника с шириной равной высоте, тоже, да.

ПК>Если ответ на (*) положительный, то, очевидно, R изменяет поведение S.


Поведение S, если вы заметили, — неизменно. R лишь "специализирует" (уточняет) расчет площади. Что вполне логично, т.к. ширина == высоте (или, другимим словами, Area == Windth^2 == Height^2) (1) — лишь один из инвариантов прямоугольника.

ПК>Если ответ на (*) отрицательный, то, вообще, неясно, какой смысл здесь

ПК>что-либо наследовать:

Смысл есть... хотя бы такой:

Пусть есть класс, реализующий поведение квадрата. Какое именно, не суть важно. Т.к. квадрат — один из инвариантов прямоугольника, то нет смысла в классе, реализующем прямоугольник, повторять реализации поведения квадрата для инварианта (1). Я могу унаследовать это поведение от квадрата, и до реализовать поведение прямоугольника выходящее за рамки инварианта (1). Все за чем нужно следить — это, чтобы применение унаследованного поведения (в смысле, как например, вызов R.Area()) в случае если прямоугольник не находится в состоянии (1), либо приводило прямоугольник в это состояние, либо было уточнено.

ПК>через S с объектами R ничего осмысленного сделать

ПК>не выйдет, т.к. Size и Area, по сути -- "вещи в себе".

Как бы это сказать-то... Это совершенно нормально! Смысл наследования не в полиморфности... она (полиморфность) вовсе не обязана возникать в следсвиии наследования (inheritance, generalization). Если нам нужна именно полиморфность поведения, то мы используем совсем друго отношение — а именно, реализацию (implementation).

Смысл наследования, как раз в том, чтобы взять готовое поведение и расширить его. Для программы, выраженой в терминах суперкласса (для агрегата суперкласса, если хотите) — это гарантированно будет означать, неизменность — во всех смыслах — его поведения. Что и имела ввиду г-жа Лисков. Рассуждая о полиморфности, она прямо указывает:

Whenever there are related types in a program there is likely to be polymorphism. This is certainly the case when the relationship is indicated by the need for a polymorphic module. Even when the relationship is identified in advance, however, polymorphism is likely. In such a case the supertype is often virtual: it has no objects of its own, but is simply a placeholder in the hierarchy for the family of related types. In this case, any module that uses the supertype is polymorphic. On the other hand, if the supertype has objects of its own, some modules might use just it and none of its subtypes.


---
С уважением, Сиваков Константин.
Re[19]: Кто автор?
От: gbear Россия  
Дата: 05.08.05 04:02
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


Спасибо за поправку... занесло. Конечно, говоря "инвариант" я имею ввиду, лишь допустимое состояние. Извиняюсь... В этом
Автор: gbear
Дата: 05.08.05
, ответе, тоже самое.

---
С уважением, Сиваков Константин.
Re[22]: Кто автор?
От: Павел Кузнецов  
Дата: 05.08.05 04:57
Оценка:
gbear,

> ПК> Т.е. одним из следствий удвоения Size является учетверение Area. Так? (*)

>
> Хм... Хороший вопрос. Для квадрата — да. Но и для, прямоугольника с шириной равной высоте, тоже, да.

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

> ПК> Если ответ на (*) положительный, то, очевидно, R изменяет поведение S.

>
> Поведение S, если вы заметили, — неизменно. R лишь "специализирует" (уточняет) расчет площади. Что вполне логично, т.к. ширина == высоте (или, другимим словами, Area == Windth^2 == Height^2) (1) — лишь один из инвариантов прямоугольника.

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

> Смысл наследования, как раз в том, чтобы взять готовое поведение и расширить его.


Если посмотреть на код, приведенный выше, то можно обнаружить, что "прямоугольник" вообще не использует поведение "квадрата", а просто-напросто разделяет с ним одно из полей. Поведение же (т.е. в формализме Барбары Лисков инварианты и набор пред-/постусловий методов) у этих классов различаются, не укладываясь в требования, выдвигаемые к отношению is-a subtype of. Причем, в обе стороны: ни множество инвариантов (ограничений) квадрата не является подмножеством инвариантов (ограничений) прямоугольника, ни наоборот.

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

И наоборот, для любого объекта прямоугольника, заданного кодом выше по ветке, постусловием изменения Size является удвоение Area. Применительно к квадратам этого не происходит никогда.

Если же ты, все таки, говоришь о наследовании реализации, то какое к этому вообще отношение имеет LSP? Да и, вообще, цитируемые работы Барбары Лисков, в которых речь идет не о наследовании реализации, а об отношении supertype-subtype, которое к наследованию реализации не относится... В общем, похоже, я окончательно потерял нить твоих рассуждений.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Кто автор?
От: stalcer Россия  
Дата: 05.08.05 05:27
Оценка:
Здравствуйте, Gaperton, Вы писали:

S>>Проблему прямоугольника и квадрата это никак не решает.

G>В JavaScript вы можете добавлять и удалять методы на лету, т. е. фактически вы можете реализовать изменение типа для объекта.

Да, об этом то я и не подумал.
http://www.lmdinnovative.com (LMD Design Pack)
Re[11]: Кто автор?
От: stalcer Россия  
Дата: 05.08.05 05:31
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Достаточно возвращать измененную копию объекта вместо изменения самого объекта, и все — вы без проблем моделируете вашу математику, не нарушая принцип Лисков.


Думаю, что это весьма ограниченное и не универсальное решение. Во многих случаях, имхо, не прокатит.
Вот если действительно иметь механизм изменения типа объекта...
http://www.lmdinnovative.com (LMD Design Pack)
Re[11]: Кто автор?
От: stalcer Россия  
Дата: 05.08.05 05:47
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Никак. В этом его слабая сторона.


Ну, почему.
— Во-первых, научились же писать программы, устойчивые к исключениям в плане утечек памяти (смарт поинтеры и т.п.).
— Во-вторых, я же отметил, что во многих случаях вся иерархия наследования принадлежит одной подсистеме, которую мы знаем, и знаем особенности поведения наследников. В особо критических случаях, если новый наследник уж совсем не укладывается в инварианты своего предка, то нужно рефакторить предка, например, добавляя в него новые методы (типа TStream.IsReadOnly). И соответственно рефакторить все зависимые от предка программы.
— В-третьих, абстрактных базовых классов, которые действительно предназначены для наследования и для которых заранее не известны гипотетические наследники, в программе не так уж и много. И в контракт таких классов я обычно неявно добавляю следующее: Любой метод может выкинуть исключительную ситуацию.
http://www.lmdinnovative.com (LMD Design Pack)
Re[18]: Кто автор?
От: Gaperton http://gaperton.livejournal.com
Дата: 05.08.05 12:29
Оценка:
Здравствуйте, gbear, Вы писали:

G>>А вот это — ошибка. Инвариант квадрата: Width == Height. У прямоугольника нет такого инварианта.

G>Хм... Т.е. для прямоугольника, состояние когда его ширина равна высоте является не допустимым?!
Вам уже ответил Павел, но повторюсь на всякий случай.

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

G>>А теперь о вашем решении (последняя попытка объяснить — ничего нового я вам сказать больше не смогу): Area — инвариант метода S::get_Size (он не меняет площадь, что совершенно естественно и ожидаемо для длины ребра квадрата), но он не является инвариантом его реализации в подклассе R::get_Size. Нарушение этого инварианта будет видимо пользователю S. При этом, исключать это из спецификации S нельзя — с какой стати площадь квадрата должна меняться при попытке узнать длину стороны?


G>Ок. Смотрим на два черных ящика
Автор: gbear
Дата: 03.08.05
.


По этому пункту совершенно солгласен с ПК. Не виду смысла так наследовать, так как при обращении к прямоугольнику по интерфейсу квадрата он ведет себя весьма странным образом. Т.е. S у вас — совсем никакой не квадрат.

Формально — нарушается инвариант бызового класса get_Size^2==get_Area, являющийся неотлемлемой частью поведения квадрата. А если вы выкинете этот инвариант из спецификации S, чтобы избежать противоречий, то S перестанет быть квадратом вообще, и станет моделировать произвольную параметрическую фигуру, задаваемую одним параметром. Причем, реализация по умолчанию будет как у квадрата, но сторонний код не должен на это закладываться, и должен работать с типом S как с произвольной однопараметрической фигурой. Более того, этот параметр Size лишен наглядного смысла — площадь от него зависит то квадратично, то линейно...

G>>Вот и все. Вы нарушаете принцып Лисков, определение подтипа и вообще все, что можно нарушить. Постусловие метода R::get_Size получается слабее, чем в базовом классе (инвариант метода преобразуется в пару предусловие — постусловие: S::get_Size true -> Area_pred==Area_post==result^2, в то время как R::get_Size true -> Area_post == result^2).


G>Хорошо, хорошо... С этим согласен. Наличие такого постусловия в контракте квадрата, бесусловно, делает такой вариант невалидным. Другое дело, что этот вариант не едиственный.


Как вы не поймете. Вы можете пытаться сколько угодно, и любой ваш вариант будет некорректен (кроме варианта с копирующими const методами), просто потому, что сделать так невозможно, и этот факт доказан. Если вы уверены в себе, я предлагаю вам очередную попытку за 50 долларов.
Re[24]: Все еще проще
От: Gaperton http://gaperton.livejournal.com
Дата: 05.08.05 13:19
Оценка:
Здравствуйте, Трурль, Вы писали:

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


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


G>>>Осталось разубедить Вас в том, что нет необходимости рассматривать всё возможное множество phi.

G>>Интересно, и как же вы это сделаете?

Т>В качестве первого шага предлагаю ограничится подмножеством вычислимых phi.

А что, невычислимое phi у нас может являеться доказуемым свойством? Пример в студию
Re[25]: Все еще проще
От: raskin Россия  
Дата: 05.08.05 14:29
Оценка:
Gaperton wrote:
> Т>В качестве первого шага предлагаю ограничится подмножеством вычислимых
> /phi/.
> А что, невычислимое phi у нас может являеться /доказуемым свойством/?
> Пример в студию

Свойство программы останавливаться. Его можно доказать протоколом
работы. Но оно невычислимо.
Posted via RSDN NNTP Server 2.0 beta
Re[26]: Все еще проще
От: Gaperton http://gaperton.livejournal.com
Дата: 05.08.05 16:06
Оценка:
Здравствуйте, raskin, Вы писали:

R>Gaperton wrote:

>> Т>В качестве первого шага предлагаю ограничится подмножеством вычислимых
>> /phi/.
>> А что, невычислимое phi у нас может являеться /доказуемым свойством/?
>> Пример в студию

R>Свойство программы останавливаться. Его можно доказать протоколом

R>работы. Но оно невычислимо.

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

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

Мы же не систему поиска вывода пишем (что, кстати, в случае исчисления предикатов сделать невозможно — оно полуразрешимо, т.е. там существуют утверждения с бесконечным выводом, как следствие — проблема вывода эквивалентна проблеме останова ).

Так что не смотря на блестящий пример, предложение Трурля отклоняется.
Re[27]: Все еще проще
От: raskin Россия  
Дата: 05.08.05 17:35
Оценка:
Gaperton wrote:
>> > А что, невычислимое phi у нас может являеться /доказуемым свойством/?
>> > Пример в студию
>
> R>Свойство программы останавливаться. Его можно доказать протоколом
> R>работы. Но оно невычислимо.
>
> Ок, проблема останова — хороший пример. Есть только один нюанс — Трурль
> шутит .
А мне нельзя.. Жаль.
> Под "свойством" подразумевается логический предикат. В
> /исчислении предикатов /нас ни в малейшей степени не волнует
> /вычислимость /этих предикатов. Потому, что нас интересует их
> доказуемость *в каждом конкретном случае*, а не вообще.

Я дал формальный ответ на Ваш (категорично сформулированный) вопрос. Я
согласен, что это как раз пример против предложенного ограничения
(останавливаемость программ как раз принято доказывать, несмотря на
неразрешимость). Ваш ответ мне является возражением Трурлю и отказом от
Вашего вопроса — разве нет?

> Ограничивать их множеством вычислимых — нахрен не нужно, так как нам не

> нужно уметь их вычислять. Если мы знаем, что свойство Х *всегда
> *выполняется на классе объектов Y, то факт наличия этого свойства уже
> доказан, все
Я знаю. Я знаю, что всякая уважающая себя (или хотя бы арифметику)
теория неразрешима или противоречива и это никому не мешает.
>
> Мы же не систему поиска вывода пишем (что, кстати, в случае исчисления
> предикатов сделать невозможно — оно /полуразрешимо/, т.е. там существуют
> утверждения с бесконечным выводом, как следствие — проблема вывода
> эквивалентна проблеме останова
Как я помню, она сложнее, хотя это никому не нужно..
Posted via RSDN NNTP Server 2.0 beta
Re[28]: Все еще проще
От: Gaperton http://gaperton.livejournal.com
Дата: 05.08.05 18:23
Оценка:
Здравствуйте, raskin, Вы писали:

R>А мне нельзя.. Жаль.

Кто вас знает, шутите вы или нет. Тэга [joke], [kidding] или (хотя-бы) смайлика я не заметил.

R>Я дал формальный ответ на Ваш (категорично сформулированный) вопрос

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

R>Ваш ответ мне является возражением Трурлю и отказом от

R>Вашего вопроса — разве нет?
Вопрос я уже задал, получил на него ответ, и отказываться от вопроса уже поздно, не так ли? А возражаю я действительно Трурлю.

Довольно забавный у нас с вами разговор получается, не находите — мы рассказываем друг другу о том, что мы друг другу говорим. У вас есть идеи — зачем мы это делаем?
Re[29]: Все еще проще
От: raskin Россия  
Дата: 06.08.05 10:43
Оценка:
Gaperton wrote:
> R>А мне нельзя.. Жаль.
> Кто вас знает, шутите вы или нет. Тэга [joke], [kidding] или (хотя-бы)
> смайлика я не заметил.
Ну, формально ответ разве был неверен? Смайлики я просто не привык
ставить, а указанные средства разметки применяю в опасных случаях.
> R>Я дал формальный ответ на Ваш (категорично сформулированный) вопрос
> Спасибо, я прекасно суть вашего ответа. Хочу только в порядке
> отступления заметить, что вопрос при всем желании нельзя "категорично
> сформулировать", его в лучшем случае можно "поставить ребром".
Да, что-то не по-русски у меня получилось.. Я имел в виду, что вопрос
мне показался подразумевающим несуществование примера такого свойства.
> R>Ваш ответ мне является возражением Трурлю и отказом от
> R>Вашего вопроса — разве нет?
> Вопрос я /уже задал/, получил на него ответ, и отказываться от вопроса
> уже поздно, не так ли? А возражаю я действительно Трурлю.
Вопрос мне показался частично риторическим. Соответственно он несёт
утверждение (как и всякий правильный вопрос...). Ваш первый ответ мне
нёс в себе утверждение, противоположное тому, которое я увидел
(возможно, ошибочно) в вопросе. Под отказом от вопроса я имел в виду
отказ от утверждения, которое подразумевалось (или мне казалось, что
подразумевается в вопросе).
> Довольно забавный у нас с вами разговор получается, не находите — мы
> рассказываем друг другу о том, что мы друг другу говорим. У вас есть
> идеи — зачем мы это делаем?
Про себя могу ответить — любимый формализм и иногда проявляющееся
желание довести его до конца. Кроме того, вот сейчас Вы мне поправили не
точное формально использование слова категоричность (за что спасибо —
побудили убедиться, что оно относится всегда к утверждению, не
подразумевающему возражений, а не к вопросу, который выглядит как
несущий в себе ответ). Если Вы считаете это бесполезной тратой времени —
Ваша воля не отвечать, в конце концов, я согласен с Вашим мнением по
исходному вопросу, и почти согласен со всем последующим.
Posted via RSDN NNTP Server 2.0 beta
Re[27]: Все еще проще
От: Трурль  
Дата: 08.08.05 05:33
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Так что не смотря на блестящий пример, предложение Трурля отклоняется.


Виноват . Как-то упустил, что речь о доказуемых свойствах.
Но тогда вопрос, как их отделять? Единственно разумным кажется рассматривать только свойства, явно указанные в спецификации класса.
Re[28]: Все еще проще
От: Павел Кузнецов  
Дата: 08.08.05 05:59
Оценка: +1
Трурль,

> Как-то упустил, что речь о доказуемых свойствах. Но тогда вопрос, как их отделять? Единственно разумным кажется рассматривать только свойства, явно указанные в спецификации класса.


Точно. Именно это и предлагает Барбара Лисков.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.