From: S Perryman on 9 Aug 2006 08:12 "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message news:17fmneyvg7la.gy9ii9nxdnyt.dlg(a)40tude.net... > On Wed, 9 Aug 2006 09:11:22 +0100, S Perryman wrote: >> Substitutability in all contexts is the Liskov/Wing subtype definition. >> Better IMHO to talk of substitutability as for one given context C, and >> two >> types T1 and T2. > Yes, this is the only way - to constrain the sets of propositions. From > the > type system perspective, it would be desirable to be able to describe such > contexts making it possible for the compiler to determine when we are in a > context of substitutability. Well, the first thing I would do is have a type system where inheritance != substitutability. The Simula regime has done wonders for programming, but IMHO a professional/intellectual laziness has seeped in regarding correctness. So if I do : /* #1 */ Square inherits Rectangle ; /* #2 */ Rectangle r = new Square(123) ; #2 is now an error raised by the type system. If I want #2, I must be explicit : Square conforms-to Rectangle ; This is design by contract. As a developer I have explicitly made the claim of conformance. And I will be held to that claim. As for describing contexts to the type system, exclusion would be useful. Square conforms-to Rectangle excludes { height(h) , width(w) } Now the type system knows that substituting a square for a rectangle will not hold for the classic Rectangle/Square example. Everything else is ok. > It is difficult to find for this any other place than type declarations. A proof system may be able to discern the contexts that hold. But we know in general there are things that can't be proved. > So in the end it is still the same > Liskov/Wing's idea of mapping substitutability to types, but approached > from the other end, in a more pragmatic manner. Indeed. Regards, Steven Perryman
From: Dmitry A. Kazakov on 9 Aug 2006 09:39 On Wed, 9 Aug 2006 13:12:42 +0100, S Perryman wrote: > "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message > news:17fmneyvg7la.gy9ii9nxdnyt.dlg(a)40tude.net... > >> On Wed, 9 Aug 2006 09:11:22 +0100, S Perryman wrote: > >>> Substitutability in all contexts is the Liskov/Wing subtype definition. >>> Better IMHO to talk of substitutability as for one given context C, and >>> two >>> types T1 and T2. > >> Yes, this is the only way - to constrain the sets of propositions. From >> the >> type system perspective, it would be desirable to be able to describe such >> contexts making it possible for the compiler to determine when we are in a >> context of substitutability. > > Well, the first thing I would do is have a type system where inheritance != > substitutability. Yes. One can inherit from a type and get a completely new, unrelated type. In Ada there is a type cloning for that: type My_Int is new Integer; as opposed to subtype My_Int is Integer; > The Simula regime has done wonders for programming, but > IMHO a professional/intellectual laziness has seeped in regarding > correctness. > > So if I do : > > /* #1 */ Square inherits Rectangle ; > /* #2 */ Rectangle r = new Square(123) ; > > #2 is now an error raised by the type system. > > If I want #2, I must be explicit : > > Square conforms-to Rectangle ; Yes. That Square is in the class Rectangle. Reuse of a type and class membership are not necessarily related things. When Square only re-uses Rectangle it obviously should form a new class. > This is design by contract. As a developer I have explicitly made the > claim of conformance. And I will be held to that claim. > > As for describing contexts to the type system, exclusion would be useful. > > Square conforms-to Rectangle > excludes { height(h) , width(w) } > > Now the type system knows that substituting a square for a rectangle > will not hold for the classic Rectangle/Square example. Everything else > is ok. Yes, I thought about it, that would be methods disallowing, or more generally, type constraining. However it might be difficult to marry with dispatching. In any case re-dispatch must be no-no. Otherwise disallowed methods might reappear. Of course inherited methods of Rectangle may still refer to height and width, that should be no problem. The difficulty is with the class Rectangle. Square is in the class Rectangle-without-height-and-width. There should be a way to find that thing back in the class Rectangle, which was designed prior Square; before constraining. >> It is difficult to find for this any other place than type declarations. > > A proof system may be able to discern the contexts that hold. > But we know in general there are things that can't be proved. Alas. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: H. S. Lahman on 9 Aug 2006 10:49 Responding to Kazakov... >>In a classic recent example here >>the debate centered around deriving Rectangle behaviors from Square >>behaviors. The real problem was that Square was defined with a >>sideLength knowledge attribute while Rectangle was defined with >>majorSideLength and minorSideLength -- apples & oranges. > > > It is not apples and oranges. It is squares and rectangles. (:-)) > > SideLength is a direct reflection of a trivial geometrical fact (theorem) > about squares. This theorem does not hold for rectangles. End of story. Not necessarily. The geometrical facts are: (A) both have four sides; (B) for a square all sides are of the same length; and (C) for a rectangle opposing sides are the same length but adjacent sides are not. So if one defined sideLengthN (N = 1..4) for Square, then Rectangle could be a subclass without any LSP inconsistency in the knowledge attributes. [One would have a different <methodological> problem in instantiating a Square in an OO context, but that's not an LSP issue per se.] > > The set of true propositions about squares is not a subset of the set of > true propositions about rectangles. In other words: > > < Squares> is a subset <Rectangles>, > > but > > <Squares + the behavior of> is not a subset of > <Rectangles + the behavior of> > > Most of LSP debates are about these apples and oranges. To believe in LSP > is as silly as to do in that Shakespeare could write in Basic English. > Isn't it a subset of English? I agree that LSP is not very practical if one tries to abstract all the features of problem space entities (i.e., make objects reusable across arbitrary problem contexts). Nonetheless I think LSP is quite useful in an OO context because one tailors object abstractions to the problem in hand. That allows one to use tricks like abstraction and a flexible view of logical indivisibility to make many LSP issues in the problem space irrelevant to the solution context. IOW, one only has to resolve the LSP issues that are relevant to the problem in hand. ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: Dmitry A. Kazakov on 10 Aug 2006 03:26 On Wed, 09 Aug 2006 14:49:13 GMT, H. S. Lahman wrote: > Responding to Kazakov... > >>>In a classic recent example here >>>the debate centered around deriving Rectangle behaviors from Square >>>behaviors. The real problem was that Square was defined with a >>>sideLength knowledge attribute while Rectangle was defined with >>>majorSideLength and minorSideLength -- apples & oranges. >> >> It is not apples and oranges. It is squares and rectangles. (:-)) >> >> SideLength is a direct reflection of a trivial geometrical fact (theorem) >> about squares. This theorem does not hold for rectangles. End of story. > > Not necessarily. The geometrical facts are: (A) both have four sides; > (B) for a square all sides are of the same length; and (C) for a > rectangle opposing sides are the same length but adjacent sides are not. > So if one defined sideLengthN (N = 1..4) for Square, then Rectangle > could be a subclass without any LSP inconsistency in the knowledge > attributes. But that wouldn't be a definition of square. Because geometrical squares form a set of things having all properties of squares, which includes the property B. Of course, you can say that B isn't essential for the problem at hand, but then I would wonder if squares aren't either. > Nonetheless I think LSP is quite useful in an OO context because one > tailors object abstractions to the problem in hand. That allows one to > use tricks like abstraction and a flexible view of logical > indivisibility to make many LSP issues in the problem space irrelevant > to the solution context. IOW, one only has to resolve the LSP issues > that are relevant to the problem in hand. True, but to me that means a defeat of LSP as a principle. It was introduced solely to ensure substitutability. When you say OK, we have to check for substitutability in each given case (context), then you merely return back to the beginning. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Thomas Kowalski on 10 Aug 2006 05:26
Hi Dmitry, Steven, maybe I didn't understood exactly what your discussion is about, but IMHO the word inheritance is not choosen well. The paradigma inheritance describes the s/w industrie is simply specialization. Every time we define an objects we are adding constraints. Each methode, each member constraints this class to an actually usable "item". Since we say an square is a special rectangle, it would be perfectly fine too have it "inheriting" is this direction, as you stated already. The Idea of breaking the "contract" with is implied by the constraints made by a certain class might be a neat feature in some situations, but is most of the time not neccessary and would just complicate the whole typesystem. Cheers, Thomas Kowalski |