Re: Question on LSP
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Tue, 2 May 2006 11:43:44 +0200
On Mon, 01 May 2006 16:35:34 GMT, H. S. Lahman wrote:
Responding to Kazakov...
However, I think that is beside the point. The issue here is whether
ClassY* is related to ClassY via subclassing or subtyping.
OK. But I don't want to distinguish subclassing and subtyping.
But they are very different! Class systems are about set membership
and identity while type systems are about property access signatures.
That might be what they are used for, but technically each class is a type.
So type relations cover the case of class ones. I don't see anything
special in classes that deserves a special treatment.
Yes. It describes referential semantics. That's a subtype. When it
describes an identity semantics, which wasn't inherited from the target
type, then it is not a subtype (in this part.) I don't see any
contradiction here, because to me there is no full subtypes, they would be
useless. Each new type is both a subtype and not, depending on which part
of semantics is considered.
I still see a contradiction. For either subclassing or subtyping there
must be a semantic link (e.g., shared properties) that is intrinsic to
both abstractions. A reference is not an object. An object is not a
reference. So one cannot make ClassY a subtype of ClassY* or vice versa.
I don't care about "is-a", I can access the target object, that's all. I
don't care about how this happens. That is an implementation detail.
Calling methods through pointers is subtyping?!? Sorry, that notion is
so alien to me that I don't even know where to push back. B-)
It looks like substitution, it works like substitution... (:-))
A pointer always gives one exactly the same thing every time it is
invoked so there is no substitution.
You mean pointer-specific operations here. But I mean that a substitution
happens when you pass pointer where an object of the target type is
expected.
That's true even if the 'thing' is
an object that is accessed through the root superclass or supertype.
The polymorphic dispatch only comes into play through which specific
object is assigned to the pointer. But once it is assigned I see no
substitution when navigating the pointer.
[Implicit] navigation *is* substitution. You "navigate" from derived type
to the base in the same way, but call it substitution. There is no semantic
difference as long as implementation is abstracted. Navigation /
substitution may include pointer dereferencing, view conversion, creation
of temporal objects, marshaling them over the network. I don't care about
this. It is hidden.
No problem again. It is not a LSP subtype in in-methods, clearly null
cannot be passed in there. But I don't care, I have generalized ClassY
exactly for that reason, to have a new value: null. Otherwise, I would use
pointers without null, some languages support them.
But that value is incompatible with the "value" (identity) of a member
of the ClassY set. In an OO context object identity exists in the
problem space and it is necessarily unique to an individual entity.
NULL is not the identity of an entity; it is a negative definition --
the value of there being no entity.
= it is not substitutable. So what? It was designed this way. You stick to
absolute substitutability, but there is no such thing in real programs.
I don't think substitutability is relevant here. A Class defines a
suite of responsibilities that all member objects /must/ share. It has
no meaning for an object without exactly those properties.
This is equivalent to substitutability in my model. Class is defined as a
set of all subtypes. So if subtyping requires substitutability (=LSP), then
class automatically enforces its properties on all objects. One could say
that the class is these objects.
The problem with this otherwise nice construct, is that because LSP is
unrealistic, one would like to relax things a bit. So some properties might
get lost. But if you ensured that no objects without properties of interest
exist at run-time, then everything would be OK again. This is like circles
and ellipses. Just don't resize that damned circles! (:-))
NULL defines
a null set of properties which is a direct contradiction of the class
definition. So that can't be substitutable semantically.
Yes, but I buy it.
The only substitutability lies in the nature of /references/ because a
reference's "value" can be defined to include a null set as well as a
class reference set. But that isn't really substitutability because the
reference isn't an object. It is just a set definition around the
reference's data domain, which is quite different than the target
object's responsibility domain.
After all you can always add Dereference_Error exception to the target type
contract and everything will be perfectly substitutable. (:-))
Apropos of the point below about our having different viewpoints, the
notion of ANY as a Mother Of Types only has academic interest for the
design of languages and whatnot. [The notion is analogous to kludges
like CObject in MFC. One only needs such things explicitly in an
application because of language deficiencies (e.g., to use dynamic_cast
in C++) or because a library designer needs a place to implement
language-specific stuff (e.g., new) behind the scenes. IOW, one should
never, ever have to refer explicitly to CObject or CObect* in
application code.]
I agree, "everything is object" is rubbish. A type without methods is
useless. But there are cases where ANY might have methods. I mean things,
which are methods, but usually aren't considered as ones. It is
1. identity
2. copying
3. other factories
4. things like sizeof()
Identity I might concede, but that is a knowledge responsibility, not a
behavior responsibility. Since inclusion polymorphism and LSP is
primarily about behavior substitution I don't think that counts. B-)
There are inner and outer substitutability. Identity is for the outer
world. It should not break clients.
In addition, object identity does not have to be explicitly defined as
an attribute because of the way OOA/D handles sets and their
relationships (i.e., identity is implicit in the way relationships are
instantiated). Finally, identity at the ANY level would have to be so
vague as to be semantically useless (e.g., how to account for compound
identifiers).
Yes, but people want containers and hash tables. I prefer ad-hoc supertypes
to ANY.
As for the other three, I argue that one will be able to find a context
somewhere where the semantic definition at the ANY level will have an
LSP violation. In fact, trying to get commercial libraries to work
together for those things is already a substantial headache.
Yes. But this is a fundamental problem of LSP.
Then how do you account for the fact that OOA/D does not even use types?
B-)
With a pity. (:-))
Again, I agree. I also agree with your point about 3GL. nGL forces you to
refrain from considering substitutability as an abstract problem. It is
true that if everything is OK, that will be automatically substitutable.
(We believe that God created our world in accordance with LSP. (:-)) But
how can you tell if your design is OK? To me the substitutability problem
is has a value of its own. I want to be able to handle it at the level of
3GL, without inspecting the problem space. The problem is the power of 3GL.
It seems that LSP is inconsistent with this power. I am not ready to
sacrifice it by going to nGL, even for the sake of LSP conformity.
So our real differences lie in the vagaries of 3GL type systems, which I
argue are not relevant at the 4GL level -- precisely because they have
been abstracted away by decoupling message from behavior. But you don't
buy the notion of a 4GL because of a Catch-22: you can't extend your
type systems to that level of abstraction, so that level of abstraction
can't exist. B-) You need to get out of the type system mud and smell
the abstractions. B-))
Sort of. But, maybe, you'll reinvent types when you will try to describe
commonalities at your abstraction level. (:-))
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
.
- Follow-Ups:
- Re: Question on LSP
- From: H. S. Lahman
- 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
- Prev by Date: Re: Class design question
- Next by Date: Re: Question on LSP
- Previous by thread: Re: Question on LSP
- Next by thread: Re: Question on LSP
- Index(es):