Re: Question on LSP
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Sun, 07 May 2006 16:57:17 GMT
Responding to Kazakov...
It seems to me that failing to preserve is-a semantics in the type systems would be much worse than choosing OOPL names like X.Y() for OOA/D abstractions like Account.withdrawal().
It is not failing, it is expressing it in a different way. When you have
virtual memory management, do you really care about physical addresses?
No. But I care very much about instantiation and two instances with the same identity are a no-no.
But you cannot use physical memory address for identity. The point is that
you have to model the identity in an appropriate way.
Actually, you can if the objects are not persisted and, with a little work, even if they are. Indirectly the OO paradigm depends upon that to allow efficient mapping into the hardware models. Ensuring that such mapping is unambiguous is one reason why one can only instantiate one object from the subclassing tree in an OO is-a relationship.
But that is beside the point. The issue here is about instantiating two objects with the same identity, regardless of the implementation of identity. That's a no-no in an OO context because referential integrity cannot be preserved during collaboration. [Even RDBs introduce compound linked identifiers to get around the problem. Since OO IDs do not have to be explicit attributes (e.g., they can be addresses), one cannot do that in an OO context. Hence subtyping instantiation is different for OOA/D and Data Modeling.]
Instantiation of types in an OO is-a context is inherently different that instantiation of types in, say, and RDB context. In OOA/D referential integrity is married to set membership and that, in turn, is married to problem space semantics. If one changes the nature of the is-a relationship in the transformation of OOA/D -> OOP, how can one guarantee unambiguous mapping for things like enforcing referential integrity?
But I can't help pointing out that nobody had much interest in type theory in general and LSP in particular until OOA/D became prominent. When the only abstractions one needed to play with were procedures, one could make do with less sophisticated graph and set theory for 3GL language design. B-) So I find it hard to believe that the type mavens weren't strongly influenced by OOA/D abstraction semantics like is-a.
It could be true or just a coincidence. Clearly we have a difficult problem
of growing complexity at hand. Old tools and customs stop working. So
people are searching in all corners. My hope is in a great unity, which
would cooptate functional and relational guys.
I don't see that level of cooperation happening real soon. B-) The OO, functional, and P/R construction paradigms are fundamentally incompatible because they have different goals and objectives.
Brain and bowel have different goals and objectives, yet they are perfectly
compatible! (:-))
But brains and bowels are the products of construction and they are constructed differently. The issue here is that the construction methods for the three software paradigms are inherently incompatible so they do not mix. I could solve a problem using an FPL in an OO manner through extensive use of monads and whatnot, but any experienced functional developer would throw up over the result. Similarly, a functional developer could solve a problem using an OOPL in a functional manner with composition and no state variables and I would throw up all over that result.
The best one can do is provide a notation that is sufficiently bland that all can use it. But the way they use the notation when they build software will remain methodologically quite different. 3GL type systems provide a sufficiently bland semantics to design specialized languages for each paradigm, but those languages will remain specialized. Nor can one talk about things like LSP unless one defines the problem space AND the construction methodology.
A good reason to give up nGL stuff which differentiates us! (:-))
But one doesn't need specialized languages at the 4GL level. I can use UML for quite general problems because it is independent of specific computing space implementations and paradigms, which 3GL are not. For example, an OOA model does not care what 3GL construction approach is used. One can use functional or P/R construction methods to implement it rather than OOP methods. [In fact, translation engines routinely target straight C for performance reasons when transforming an OOA model in R-T/E environments. It would be a lot tougher to target an FPL properly because of the way the OO paradigm manages state, but theoretically it's possible.]
It does not, it has a potential to become. Is-a is abstracted as "is
substitutable for" and the latter is as "inherits this method from."
Another fundamental disagreement. "is-a" does not imply anything at all about substitutability. Is-a is abstracted as "is a member of that set". Nothing more.
I am constructivist, show me the set! (:-))
The set is any set in the tree. The is-a relationship is just a Venn Diagram in tree form; nothing more. It is in tree form because that makes it convenient to deal with the fact that each set is defined in terms of another set (of properties).
Ah, but I have no objection to is-a defined on properties. I do to is-a
defined on values and objects. The first can imply the latter only if you
have a special sort of identity, which is a property itself. I just don't
consider the latter. It is irrelevant. Anything I want to say about objects
I do in terms of properties.
OK. In the end classes and types share a notion of definition in terms of properties. That is what allows them to be mapped between OOA/D and OOP.
But there is still nothing in an OO is-a relationship that says anything about "is substitutable for". In fact, in the Venn Diagram sense objects of one subclass are not substitutable for those in another subclass (i.e., one cannot move objects from one subclass to another). The substitution only enters the picture through polymorphic dispatch during collaboration with objects outside the is-a relationship.
I would say LSP is relevant to any relationship.
1 grades *
[Teacher] -------------- [Student]
All members of the [Student] set have identical properties, including identical behaviors. Same thing for all members of the [Teacher] set. No matter what collaborations take place over that relationship, the same behaviors are involved, regardless of individual member identity (i.e., which instances actually participate in the collaboration). In transforming to 3GL code, each class would be mapped to a single type. Thus there is no behavior or type substitution in any conceivable collaboration. So how can LSP be relevant?
In aggregation? I don't see it as types relationship. But I always wished
to go this way to its logical end, i.e. to have abstract record and array
types. Then teacher would be derived from that type, and student from
associated abstract member type. I suppose it is the same discussion as one
about pointer. The idea is to treat all types relationships uniformly, as
subtyping.
Yech. You must have had a traumatic encounter with functional programming in your formative years. B-)
However, I don't see it as a types relationship either. That's kind of my point about OOA/D not using type systems. B-) However, to implement it at the 3GL level one will have to deal with a type when mapping collaboration messages. But there will still be no type substitution involved because any Teacher always accesses any Student through a single Student type (and vice versa).
That's OK, but it is already beyond types. I want (and I think Liskov did
too) to judge about types regardless to what they implement.
I agree it is beyond the semantics of pure types. But it is not beyond the semantics of substitution of types. IMO, Liskov's original question (which Daniel T. quoted) was a philosophical question about what one /does/ with types. She asked, "What does it mean...". That question seems to me to be about the context semantics rather than the type semantics.
That cannot be answered. What does it mean to add? Nothing, full stop.
Scientific answer is elusive: try numbers, they can be added, try
probability measure it is additive, etc.
OK. But she proceeded to /define/ substitutability in terms of types from the client perspective, which limited the philosophical context drastically. The True Meaning then becomes academic, along with the number of angels one can fit on the head of a pin. Nonetheless, she was defining something that was beyond the semantics of types themselves.
Hmm, I could have fat pointers and thin objects. This is actually what
always wished to see in modern OOPL. Technically it means that the type tag
is not stored in the object (that will have no type identity). It is in the
pointer. Note that semantically fat-pointer-to-thin-value is equivalent to
thin-pointer-to-fat-value. Both dispatch, both are dynamically polymorphic.
But it breaks your "is-a" fiction. BTW, having this mechanism, you will be
able to translate your OOA/D "is-a" much more uniformly and efficiently.
I think all you are doing is moving the interface definition (type) out of the object into into the message addressing mechanism.
Abstracting dispatching mechanics? Not really, pointer is an object to me.
It can be of class (fat) or of type (thin) [but never both]. It is just a
consequence of my view on pointers as subtypes.
Fine. But it is all still specific computing space implementations of how one sends an OOA/D message from [Teacher] to [Student]. None of it is relevant to the semantics of collaboration in sending those messages. And none of it is relevant to LSP substitutability. LSP only becomes relevant when one changes the nature of [Student] so that it is subclassed (or subtyped) while the collaboration remains with the root class. Then and only then does one have type or class substitutability and it has nothing to do with specific implementations.
As an analogy consider that I can describe any complex behavior with interacting state machines using asynchronous event-based communications. Almost always the state machine actions will be executed at some lower level by making synchronous procedure calls. Does that make a synchronous procedure call inherently asynchronous? No. Like a pointer, it is just an implementation artifact. In this case that call is /inherently/ synchronous even though it implements an asynchronous solution. So the synchronous procedure call has no more to do with asynchronous behavior than a pointer has to do with polymorphic dispatch.
Agree, but why do you think that this supports your point of view and not
mine?! (:-))
LSP can only exist if there is type substitution. One can only have type substitution if there is polymorphic dispatch. Pointers can implement any sort of dispatch.
I consider only one particular case, where target operation is accessed via
pointer. It is a perfect type substitution. It is also polymorphic
dispatch:
If Foo can be called on T and on T* then there exist a polymorphic
subprogram defined on the class T U T*. The polymorphic subprogram has two
bodies:
1. Foo which works on T
2. Foo o "*", which works on T* ("*" is pointer dereferencing operator)
So when you call Foo on a pointer it is a polymorphic call that resolves to
the body 2.
But T* is an intermediary; an indirection. It has nothing to do with and knows nothing about T's properties. Foo can only be called on T. When the client invokes Foo, it is always from T, regardless indirection or what language implementation mechanism is used for addressing a T. That's why modern OOPLs don't make a distinction and always address T.Foo. The fact that the language always introduces a hidden T* is a pure language implementation issue.
Again, I see no LSP substitution unless T* can provide either a T1 or a <different> T2, which is polymorphic dispatch, which is enabled by the target being an is-a leaf member (T1 or T2) AND the client accessing it at the T superclass level. But from the pointer's viewpoint it knows nothing about T1 and T2; it is always dealing with a T type and there is no substitution.
*************
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
.
- Follow-Ups:
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- References:
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- From: H. S. Lahman
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- From: H. S. Lahman
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- From: H. S. Lahman
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- From: H. S. Lahman
- Re: Question on LSP
- From: Dmitry A. Kazakov
- Re: Question on LSP
- Prev by Date: Re: Searching OO Associations with RDBMS Persistence Models
- Next by Date: Re: Searching OO Associations with RDBMS Persistence Models
- Previous by thread: Re: Question on LSP
- Next by thread: Re: Question on LSP
- Index(es):