juan_gandhi: (Default)
[personal profile] juan_gandhi
It's a known puzzle from the depths of object-oriented teaching: is Circle a subclass or Ellipse. From school we know it is; but as we read in books, for programmers, it is not. How come? Oh, "Liskov principle". They use Liskov principle to scare kids.

Actually we know that a circle is an ellipse with both axes being the same length.

But in programming, an ellipse is something different. It is at least stretchable. And it is also moveable. Somehow it is not rotatable, but we can skip it for simplicity.

An ellipse in programming is (almost) always horizontal; it can be moved (by changing coordinates of its center) and it can be stretched/compressed by changing its height and width. Sure a stretchable ellipse is neither an ellipse nor a circle, not even a stretchable circle. A stretchable circle stretches equally in all directions.

That's it, no? Questions? Objections?

Date: 2011-01-24 08:07 pm (UTC)
stas: (Default)
From: [personal profile] stas
"is a" in the language is quite informal - when they say "pessimist is a well-informed optimist", they don't mean pessimist-optimist relationship should follow the LSP.

BTW, when I was a kid, I was being scared by sqare-rectangle example, not circle-ellipse.

"pessimist is a well-informed optimist"

Date: 2011-01-24 08:27 pm (UTC)
From: [identity profile] alextr98.livejournal.com
optimist is a well-instructed pessimist!

Date: 2011-01-24 08:23 pm (UTC)
From: [identity profile] anhinga-anhinga.livejournal.com
This is basically, "covariance vs. contravariance dillema" in subtyping: if A is a subtype of B, is A->C a subtype of B->C (covariance), or is B->C a subtype of A->C (contravariance).

Liskov principle corresponds to contravariance.

Date: 2011-01-24 09:48 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
I don't think so. I believe it is about the kind of arrow from A to B, is it a mono, is it an epi, can it be represented as an epi followed by a mono...

Date: 2011-01-24 10:05 pm (UTC)
From: [identity profile] anhinga-anhinga.livejournal.com
People who advocate type systems with contravariance typically appeal to substitutability -- which is essentially what "proper inheritance" is about.

These people also claim that they are very "categorical", even extending Curry-Howard isomorphism to cartesian closed categories (http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence#Curry.E2.80.93Howard.E2.80.93Lambek_correspondence).

This does not mean that they are right, but this is smth to keep in mind... (I tended to dislike contravariance when I was thinking about functional programming in the 1990-s, in particular, because I thought it was a bad idea to mimic object inheritance, and because of other reasons [one is that this results in "non-extensionality" [multiple points representing the same function from A to B in the models], but I did not like categorical models in software either back then. So, basically, if you come up with a viewpoint which would be categorical, but would decouple these things [proper inheritance and contravariance], it would be something different from mainstream [and might be better, but you would have to argue explicitly against the mainstream viewpoint here].)

Date: 2011-01-24 10:56 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Actually, I do not think I have a ready solution for disambiguating two categories, one with all functions, another with just inheritance.

I do not see the importance of substitutability, but is not it true that some functors are contravariant?

Date: 2011-01-25 01:33 am (UTC)
From: [identity profile] anhinga-anhinga.livejournal.com
> is not it true that some functors are contravariant?

sure; it's just that if one wants a system where subtypes are subsets, and functions are extensional ( (f, g: A -> B, and for all x from A, f(x) = g(x)) implies f = g), then this one cannot be contravariant (assuming that I have not made a mistake when "proving" that).

> I do not see the importance of substitutability

I think it is quite essential in justifying rules for various mainstream systems of types lambda calculus (e.g. parametric polymorphism of ML and similar systems); although it really becomes explicit, when one enriches a system like that with subtypes.

So here is a logical fork, which depends on whether one likes this class of type systems. If one likes these type systems, then it probably matters that this class of type systems comes from people who think that substitutability is quite key here (although it still does not mean that one has to agree with them, but their arguments should be considered).

Alternatively, one could decide that one does not like this class of type systems, and that inference rules should be different (like I was thinking in the 90-s; now I don't have a firm opinion). Then it's quite likely that substitutability would not be involved.

Date: 2011-01-25 06:58 am (UTC)
From: [identity profile] anhinga-anhinga.livejournal.com
> I think it is quite essential in justifying rules for various mainstream systems of types lambda calculus (e.g. parametric polymorphism of ML and similar systems); although it really becomes explicit, when one enriches a system like that with subtypes.

After refreshing it in my memory, the canonical way to think about it in the mainstream school of thought is as follows. One considers a universal set D of all untyped lambda-terms (or of their equivalence classes). Types are just some subsets of D. When a lambda-term belongs to the subset X, we say that this term is of type X. Subtypes are subsets. A term f is said to be of type A->B, if whenever term x is of type A, term f(x) is of type B. Here we have contravariance and substitutability, and they are the same thing (easy to see), but we don't have extensionality (because the terms can be equivalent on the inputs from A, but can behave quite differently, when the inputs are outside of A).

Also, the resulting type systems are quite horrible (IMO) in two ways. On one hand, they are strongly normalizable, and lambda-terms without normal form are never typable, so the recursion and Turing-completeness have to be added by ad-hoc methods. On another hand, the inference is usually too strong, so, for example, one can write a pathological sequence of well-typed programs in ML, such that the size of their types is exponential of the size of the program as a directed acyclic graph (and doubly exponential as a linear output) and hence the compiling time is also exponential. And this "compiler bug" is built-in as a design feature right in the heart of ML and languages with the similar type systems (it does not really occur in practice, one has to work to create this pathology, but it's an ugly property of the type system and of the language).

Date: 2011-01-24 08:45 pm (UTC)
From: [identity profile] justy-tylor.livejournal.com
Это онтологический вопрос - сначала определяются термины.

В одной онтологии ont1:Круг и ont1:Эллипс могут быть отдельными классами, элементы которых частично пересекаются. В другой классы ont2:Круг и ont2:Эллипс не пересекаются - "если Круг, то уже не Эллипс". В третьей ont3:Круг явно описывается как подкласс ont3:Эллипс.

Разные определения эллипсов это разные классы, нельзя заявлять об их идентичности. Но тройка классов ont1:Круг, ont2:Круг и ont3:Круг содержит одни и те же элементы. Как и классы ont1:Эллипс и ont3:Эллипс содержат те же элементы, что объединение классов ont2:Эллипс и ont2:Круг.

Далее смотрим: про эллипсы нигде не указано, что они могут или не могут двигаться. Но даже подвижность и неподвижность могут рассматриваться и как возможности, и как ограничения. Тогда появляются, например, ont4:НеподвижныйЭллипс (пересечение классов ont4:Эллипс и ont4:НеподвижныйПримитив) или ont5:ПодвижныйЭллипс (пересечение классов ont5:Эллипс и ont5:ПодвижныйПримитив).

При переходе к архитектуре ПО выбор между ont4 и ont5 начинает сильно зависеть от используемых средств (языков программирования, etc). А верхняя онтология "что есть Примитив" (как онтология, API или описание формата данных) тоже может быть задана извне, где-то в требованиях по interoperability продукта.

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

Date: 2011-01-24 09:05 pm (UTC)
yigal_s: (Default)
From: [personal profile] yigal_s
> From school we know it is

We do, but in schools they teach 'constant' circles and ellipses (functional style :-), so say, objects with quite limited interfaces. For which Liskov's works pretty well.

> sure a stretchable ellipse is neither an ellipse nor a circle

Stretchable ellipse is an ellipse. Why not?

> A stretchable circle stretches equally in all directions.

It may stretch unequally, but then it changes its type, if we are smart enough to implement consistently such a magic.

Bottom line: how would I design stuff like that? No idea. One approach is to abandon type system and use dynamic languages. If we want to have static type system... I have no idea whether such a thing has been designed already. Luca Cardelli might have wrote something about it. And... nobody said a perfect object-oriented type system is possible for design. OOP is not exactly about the real world, it is not promised to always work and always solve our problems, especially in compile time.

Date: 2011-01-24 09:52 pm (UTC)
From: [identity profile] uspenskiy vladimir (from livejournal.com)
http://en.wikipedia.org/wiki/Dependent_type, if I am not mistaken.

Date: 2011-01-24 09:59 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Check out lambda cube...

Anyway, why stretchable ellipse is not an ellipse... it depends on the axiom of choice actually. If it holds, it is; if we do not assume the AC, it is not. Stretchable ellipse is an equivalence class.

Date: 2011-01-25 03:21 am (UTC)
yigal_s: (Default)
From: [personal profile] yigal_s
* it depends on the axiom of choice actually

How comes? In what way?

Date: 2011-01-25 03:58 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
See, a stretchable ellipse is a class of ellipses. There's an epimorphism from ellipses to stretchable ellipses; the fact that this epimorphism splits is due to AC: see http://ncatlab.org/nlab/show/axiom+of+choice (http://ncatlab.org/nlab/show/axiom+of+choice).

I can give you an example when this is not the case.

Imagine a curve in space that projects (vertically) on an ellipse. This curve loops twice, in space. So for every point on ellipse there are two points projecting onto it. If we limit ourselves with continuous mappings only, we cannot split this projection.

Date: 2011-01-24 09:18 pm (UTC)
From: [identity profile] huzhepidarasa.livejournal.com
Этому безобразию пора уже положить конец.

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

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

Ну, если мы пишем MS Paint, это нормально. Но в Paint эллипс и окружность не обязаны быть подтипами ни друг друга, ни чего-то третьего (разве что абстрактного типа Shape). Там это просто не нужно.

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

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

Как-то так.

Date: 2011-01-24 09:51 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Об этом и речь. Класс (эквивалентности) эллипсов, взятый по модулю аффинного преобразования - это совсем не то, что класс неподвижных и неизменяемых эллипсов.

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

Date: 2011-01-24 09:51 pm (UTC)
From: [identity profile] igorlord.livejournal.com
To be a subclass, you have to be able to do everything that your superclasses can.

A circle cannot be a subclass, because eclipse can have radii of different lengths, but circles cannot.

An elipse cannot be a subclass, because circles know their radius, but elipses cannot (they do not even have such a concept).

Date: 2011-01-24 09:54 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
It is confusing. When you write, in Java, extends - does it mean you extend something or limit something? Do you think red circles form a subclass of circles? How about visible circles?

What can an ellipse do that circle cannot, tell me. Define a circle as an ellipse with two equal axes, and that's it.

Date: 2011-01-25 03:03 am (UTC)
From: [identity profile] igorlord.livejournal.com
"extends" means that you are *extending* something by giving it new abilities. But you must never limit that something when extending! That's all.


So if you had color-blind circles, then "colored circles" is a subclass (i.e. -- it adds an ability of a circle to know its color). Now, if your "colored circles" could never change color, then you could also make "red circles" a subclass of "colored circles", since you would not be removing any abilities. But if your "colored circles" could change colors before, then "red circles" is not a subclass.

Same analysis about "visible circles".


> "What can an ellipse do that circle cannot"?

If an ellipse object cannot change its shape (cannot change the radii independently, for example, via setters), then, indeed, a circle is a fine subclass of "ellipse". If ellipse radii were mutables, however, you would be taking away that ability, which is not allowed.

Date: 2011-01-24 10:57 pm (UTC)
From: [identity profile] anton-solovyev.livejournal.com
I have been burned so many times by using subclassing/inheritance, that now anything other than simple interface implementation or implementing an abstract class is almost never used.

Looks like this whole idea of designing class hierarchies is not very useful, other than as far as refactoring goes. With the addition of the "you ain't gonna need it" principle, that means that if you can make the code clearer/more compact, then use the inheritance, otherwise don't bother.

Also, I find myself using inheritance not at the design stage, but at the refactoring stage. Code it up first, extract superclasses later if that makes sense.

So, to me this question is more of a "how many angels can dance on the head of a pin?" thing.

Date: 2011-01-25 01:56 am (UTC)
From: [identity profile] cema.livejournal.com
I have been burned so many times by using subclassing/inheritance, that now anything other than simple interface implementation or implementing an abstract class is almost never used.

Yeah, something like that.

I find myself using inheritance not at the design stage, but at the refactoring stage. Code it up first, extract superclasses later if that makes sense.

Interesting. This implies "exploratory" programming. Does it mean if we had a solution beforehand we would not need inheritance? (Apparently, of classes, not interfaces?)

Date: 2011-01-25 03:28 am (UTC)
From: [identity profile] yatur.livejournal.com
I agree. Most of the time I use composition instead of imlpementation inheritance. Composition gives us better testability and control (e.g., two "super" objects can share the same "sub" object, which is impossible with inheritance).

Most inheritance attempts die when asked "can X have more than one Y". Can a car have more than one steering wheel? Well, yeah, why not. It would be a weird car, but it is quite possible. So, car is not a subclass of steering wheel.

There are, of course, other tests, but this one weeds off the vast majority of inheritance candidates.

Date: 2011-01-25 03:20 am (UTC)
From: [identity profile] yatur.livejournal.com
The thing is, mathematical objects are implicitly considered immutable, while OOP objects are (were) implicitly considered mutable ("stretchable circles, movable ellipses, etc.).

Thus, blindly transferring mathematical concepts to programming can create a lot of confusion.

Immutable circle is an immutable ellipse, and LSP here holds just fine. Mutable circle may or may not be a mutable ellipse, depending on the nature of allowed mutations. E.g. movable circle is a movable ellipse, but stretchable circle is not a stretchable ellipse, because a circle cannot be stretched the way an ellipse can be.

So, yes, you a right. The culprit is stretchability, as a particular case of mutability. This destroys the IS-A relationship between immutable objects.

Date: 2011-01-25 03:49 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
How about talking of a class of ellipses?

Date: 2011-01-25 05:05 am (UTC)
From: [identity profile] yatur.livejournal.com
I am not sure I understand the question.

For me "class of ellipses" is either the set of all ellipses, or something akin to typeof(Ellipse) or Ellipse.class. Of course, this is distinct from the class of circles.

Date: 2011-01-25 05:11 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
By "class of ellipses" I mean equivalence class. Yes, it is different from class of circles (in both cases:)

Date: 2011-01-25 07:58 am (UTC)
From: [identity profile] cema.livejournal.com
equivalence class

On what morphisms? A mathematical circle is not the same as the Circle type/class/whatever you defined in a program.

Date: 2011-01-25 04:11 am (UTC)
From: [identity profile] yms.livejournal.com
А тут (http://en.wikipedia.org/wiki/Circle-ellipse_problem) усё уже и написано...
Edited Date: 2011-01-25 04:11 am (UTC)

Date: 2011-01-25 05:20 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Нет. Там усё написано с точки зрения индийского университета 2000-го года. А мы как бы глубже копаем. Вся идея состоит в том, что растяжимый эллипс не является эллипсом. И эллипс не является растяжимым эллипсом.

Путаница примерно как если бы мы не могли различить вещественное число и множество вещественных чисел.

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

Date: 2011-01-25 07:12 am (UTC)
From: [identity profile] yms.livejournal.com
Я это воспринял как вариант решения "сделать объекты постоянными". Но если дело в назывании вещей, тогда да.

Date: 2011-01-25 07:13 am (UTC)
From: [identity profile] yms.livejournal.com
Впрочем, нет. Сказать "растяжимый эллипс - не эллипс" ничуть не лучше, чем "круг - не эллипс".

Date: 2011-01-25 05:54 pm (UTC)
From: [identity profile] anatoly borodin (from livejournal.com)
Являются ли действительные числа комплексными, если комплекмному нужны две переменные, а действительному — одна? :)

Date: 2011-01-25 09:26 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Про действительные числа я не знаю, а вот про вещественные - уверен.

Но вопросы стоят более серьёзные; напишу отдельным постом.

Date: 2011-01-25 09:57 pm (UTC)
From: [identity profile] anatoly borodin (from livejournal.com)
> Про действительные числа я не знаю, а вот про вещественные - уверен.

Это одно и тоже.

Ну так и с эллипсами та же ситуация. Если сделать мутабельные числа, то можно ли умножить 3 на 1 + i?

Date: 2011-01-25 11:05 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Что такое мутабельные числа?

Date: 2011-01-25 11:12 pm (UTC)
From: [identity profile] cema.livejournal.com
2 пишем, 3 в уме.

Date: 2011-01-25 11:22 pm (UTC)
From: [identity profile] anatoly borodin (from livejournal.com)
То же, что мутабельные эллипсы с окружностями.

MyReal x(2);
MyComplex y(1,1);

x.setValue(10);
x.multiplyBy(y);

Date: 2011-01-26 12:07 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Ага, это лучше эллипсов. Но я как бы перестал понимать, в математическом смысле, что это такое.

Date: 2011-01-26 01:18 am (UTC)
From: [identity profile] anatoly borodin (from livejournal.com)
В математике ж вроде mutable объекты не рассматриваются? sin(t) завист от t, но сама функция sin :: a -> a остаётся immutable.

Можно было бы спокойно эллипсы и окружности таскать by value, и конвертировать, если надо — как округляется double при приведении к int, например. Но всё упирается в производительность, память и старые вредные привычки вроде «на питоне я могу таскать туда-сюда целые массивы, а на плюсах всё должно быть оптимально!»

Мне так кажется. Но надо ещё подумать.

:-)

Date: 2011-01-25 08:01 am (UTC)
From: [identity profile] cema.livejournal.com
Короче: долой классы, да здравствуют интерфейсы.

movable и stretchable

Date: 2011-01-25 11:48 am (UTC)
From: [identity profile] freedom_of_sea.livejournal.com
нужно делать на предках вообще

Date: 2011-01-25 01:07 pm (UTC)
From: [identity profile] nivanych.livejournal.com
Все военные знают, что эллипс - это круг, вписанный в квадрат 3*4.

Date: 2011-01-25 11:06 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
То ли дело.

Date: 2011-01-27 02:30 pm (UTC)
From: [identity profile] nivanych.livejournal.com
"Эллипс", в понимании написнаного, расширяет класс.
Описать интерфейс класса можно терминальной коалгеброй или изящнее, терминальной диалгеброй.
В таком понимании, вполне очевидно, что от класса "окружность" есть мономорфизм в "эллипс".
Правильно выше сказали - "долой классы, да здравствуют интерфейсы", с ними-то всё ясно.

Date: 2011-01-27 04:50 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Wow. Вот спасибо!!!

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

June 2025

S M T W T F S
1 2345 6 7
8 9 10 11 121314
15161718 1920 21
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 24th, 2025 08:59 am
Powered by Dreamwidth Studios