Re: Question on LSP
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Thu, 4 May 2006 15:10:53 +0200
On Wed, 03 May 2006 16:18:08 GMT, H. S. Lahman wrote:
Responding to Kazakov...
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.
But this is comp.object where subclassing and subtyping are used (and
only used!) to express is-a relationships.
But is-a in the problem space is not is-a in the programming language. It
is very dangerous to mix them. I can model problem space's is-a by many
ways, and many of them will not be is-a. In my view, subtyping expresses
nothing. It is a relation which can be evaluated to true or false. Same as
an integer number, which also expresses nothing. We can use either to model
something that in our opinion has a similar structure / behavior / shape /
properties. I stop, where you begin.
This just underscores the nature of our disagreement. I don't care
about linguistics and 3GL grammar design. So to me one cannot talk
about subclassing or subtyping or LSP without an is-a context. That is
exactly why I cannot see ClassY* being related to ClassY through any
sort of subtyping (outside the language design meta model).
Yes, you are trying to bring a problem space, while I am trying to abstract
all them away.
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.
I see this as a quite different issue that has nothing to do with
pointers per se. There are three aspects of OO relationships that one
has to deal with during OOA/D/P: implementation, instantiation, and
navigation.
Pointers are <one of several> implementation mechanisms for
relationships at the OOP level. That implementation is fixed regardless
of the dynamics of collaboration. Passing the pointer as a method
argument is <one of several> mechanisms for navigating OOA/D
relationships at OOP time.
Your substitutability, OTOH, is an issue for instantiation. If the
pointer, whether passed or as an embedded attribute, is never changed
after the initial instantiation, then there is no substitution; the
receiver always sees exactly the same object with exactly the same
behaviors. If the pointer is instantiated differently each time it is
passed (or an embedded pointer attribute is reset) before each
navigation, then one has your substitutability because the receiver now
interacts with a different object with different behaviors during each
collaboration.
You consider here individual objects. But types and their relations aren't
about that. "Pointer does not change" is misspelled. "Pointer is
changeable" were correct. Types are talked of in conjunctive mood, so to
speak. There is no objects so far, only values.
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.
But subclassing relationships are not navigable. In an is-a
relationship, like Highlanders, There Can Be Only One. That's why the
dynamic_cast in C++ represents a language deficiency. In an is-a
relationship, there is only one object in hand at a time that
incorporates the entire tree so there is nothing to navigate.
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."
I see that as the issue with pointers. One always gets the same object
regardless of whether the referenced object is a member of a subclass or
not. So there is no substitution unless one can instantiate the pointer
differently for each collaboration at run time through some sort of
dynamic dispatch mechanism. And that has nothing to do with the nature
of pointers themselves because the instantiation is at a different level
of abstraction. Thus in the GoF pattern:
* R1 1
[Client] --------------- [Strategy]
A
| R2
+------+------+
| | |
... ... ...
The substitutability lies in instantiating R1 at run time.
OK, if you mean a possibility to instantiate values of S as ones of T. Why
T* cannot be instantiated as T?
But R1 can
be implemented in a variety of ways besides pointers or argument
passing, so those implementation details aren't crucial. Similarly in
any given collaboration between Client and Strategy there is no
navigation of R2. One gets exactly the object that was used to
instantiate R1.
IOW, LSP and substitutability are related to the dynamic dispatch
mechanism for instantiation, not the pointers, argument passing, or
other 3GL relationship implementation details.
But you can dispatch on pointers. Then dispatch happens only upon argument
passing etc. If you agree that pointer is an implementation detail, why
then cannot you accept that this detail could be one of some implementation
of substitutability?
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.
LOL. So just what are you buying in contrast here? That NULL is
useful anyway? That there can be non-semantic substitutability?
Yes, I agree with the answer you gave below:
[I buy the notion that there are orthogonal semantics contexts, such as
language design, where my objections don't carry. So in such contexts
one could think of values as objects, references as objects, and
reference types and object types are related through subtyping.]
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. (:-))
Not in a well-formed OOA/D. B-)) That would lead to a cohesion problem
for the target abstraction. Whatever the problem space entity
underlying the target abstraction has as intrinsic characteristics, they
surely doesn't include exception processing.
Ah, that nGL again! (:-)) Exception processing is not necessary a model. It
could serve for "phase transition." You might be unable to have one model
working well in all cases, just because the solution space has a structure
of its own. You have to handle "bifurcations" by changing models. (Not
everything is a model. I am *not* a translationist, as you know! (:-))
However, I was thinking of knowledge
attributes in general. On thinking about it, I have to retract this
particular statement because knowledge attributes can be the root of LSP
problems. I have seen Shape trees where the real problem was that
completely different knowledge <private> attributes were defined for
subclasses and superclass for the same semantics:
Rectangle:
majorSide.
minorSide.
Square:
side.
This is just asking for trouble with the behavior substitutability
because the implementations that the behaviors assume are incompatible.
I don't see it as the problem. Both are just implementations, they could be
any. The problem is in what they model, in the problem space. Circle is not
substitutable for ellipse already there.
--
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
- From: Dmitry A. Kazakov
- Re: Question on LSP
- From: H. S. Lahman
- Re: Question on LSP
- Prev by Date: Re: Question on LSP
- Next by Date: Re: Question on LSP
- Previous by thread: Re: Question on LSP
- Next by thread: Re: Question on LSP
- Index(es):
Relevant Pages
|