Re: Question on LSP
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Thu, 11 May 2006 11:49:14 +0200
On Wed, 10 May 2006 17:25:39 GMT, H. S. Lahman wrote:
Responding to Kazakov...
Since OO IDs do
not have to be explicit attributes (e.g., they can be addresses),
They cannot be addresses, because addresses may change during program
execution. ID has a definite type. One can use for this purpose the type
Machine_Address. But only under some circumstances, namely when
Machine_Address implements the contract of ID. So it is first identity,
then address, in that order, not in reverse.
All the OO paradigm requires is that identity in the problem space be
unique. There is no problem with using addresses as identity in the
implementation so long as referential integrity is preserved somehow.
(Which is primarily an OOP problem.) That will be more difficult if one
moves objects, but it is still a routine problem for things like
home-grown memory managers.
It is far from trivial. There is aliasing problem. There is a problem of
stored addresses. There is a problem of same thing having different
equivalent addresses in the same context. There is a problem of addresses
depending on the context etc.
At the OOA/D level identity is abstracted so that identity need not be
explicit. However, consistency with address identity is implicit in the
way OO relationships are defined and instantiated at the OOA/D level.
IOW, the OOA/D relationship paradigm is /designed/ to be readily
implemented with addresses because that is the most efficient mechanism
for a memory resident application. That's not true for relationship
paradigms like those used in RDBs, which are comparatively inefficient
when used in memory.
Look at your types that define objects in the OOPLs in a practical
application. Where is the object identity? Most of the time the type
definition has no mention of it at all. But every object in memory is
uniquely identified by its current address in memory and that identity
is what is used ubiquitously by references, offset tables, and whatnot.
No, this is the crux. If I don't contract identity, then there is *no* one.
That precisely means that there is no legal way to identify any given
object of this type. They all are indistinguishable. If OOA/D identifies
some objects as having identity, then that must be explicitly specified in
the corresponding type contract using available language gears.
To what extent the difference in methods influences one in languages and
reverse? Isn't it so that one cannot mix methods just because there is no
way do describe them same language? If the goal to have one language per
one construction method, then indeed there is little hope. But why it
should be the goal?
I think it is far more than just the language. It is about the overall
construction paradigm.
For example, one can implement a state machine using either a Moore or
Mealy model. But the Moore model is much more natural to OO development
while the Mealy model is much more natural to procedural or functional
development. The models themselves are mathematically equivalent and
completely interchangeable but they make a very big difference to the
way one /thinks/ about solving the problem in hand.
Why construction paradigms cannot be equivalent? In the sense that you were
be able to impartially judge about their applicability in each concrete
case?
However, the OO is-a relationship involves multiple distinct types whose
property sets are different.
[T]
A
|
+------+------+
| |
[T1] [T2]
Type [T] has some fixed set of properties. Type [T1] has a set of
properties that include [T]'s plus some additional specialized
properties. Similarly type [T2] has a set of properties that include
[T]'s and its own, unique specialized properties. Objects will /always/
be instantiated as either a [T1] or a [T2].
[Languages like C++ that allow instantiation of just a [T] object are
broken. One inevitably gets in trouble in during maintenance when
subclasses are added because referential integrity is ambiguous; some
members of [T] are defined as negatives (i.e., NOT members of the
existing subsets). Note that such implications are not so obvious in a
type system, which is why we have broken OOPLs. That's one reason why
it is important to get the OOA/D right in terms of class sets before
going to OOP's type interfaces.]
Well, clearly, pure interface substitutability has less problems. But there
are important cases where T is not just an interface.
Types [T1] and [T2] are not substitutable for any of the specialized
properties of [T1] and [T2] under any circumstances. However, they are
<supposed to be> substitutable for the properties defined by [T]. There
are two access possibilities:
Yes, but again there are cases where the graph above has cycles. I.e. when
you might want to use T1 and T2 interchangeable:
[T1] <------> [T2]
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).
Yes, it is not a substitution between Teacher and Student, it is between
Abstract_Referential_Containter and Teacher; Abstract_Referential_Element
and Student. It should be a sort of abstract relational algebra
instantiated in Teacher/Student pair.
You've lost me again because I think you are designing languages rather
than solving problems. Surely your 3GL code is not going to have things
named Abstract_Referential_Container anywhere in it(?)
No instances of. But the type itself (Abstract_Referential_Container) could
be a thing. At least its identity (type tag) is a thing in practically any
language.
BTW, it is a message sent to the pair (Teacher, Student).
You have lost me again here. I think you must be designing OOPLs again.
B-)
Very much so! (:-))
Relationships can be bidirectional but individual collaborations
(messages) among participating objects are always one-way. That is, a
Teacher can send a Student a message and a Student can send a Teacher a
message over the same relationship, but there aren't any messages to
both. OOA/D collaboration is always peer-to-peer (i.e., the 'to' is
literal).
It is a ve-e-ry restrictive view. This way you indeed will not be able to
get RM guys on board.
BTW, a litmus test for any theory, starting since Cantor times is - how do
you construct numbers in your paradigm? (RM people are of course unable to
answer this in any reasonable way.) What about your model? Let you have Z
and Q. Along which relationship does "+" sent?
It knows that T has Foo, this is what allows you to do Ptr.Foo (). Only
typeless pointers know [almost] nothing. But we don't want them at all.
T knows, but not T*. T* is simply an indirection to get to a T.
Note that the language allows us to use a name like 'T' on the reference
as a mnemonic so that the developer can keep track of what is happening
with the indirection. Object* would be perfectly acceptable as an
indirection mechanism in providing correct code. But the code would be
rather unreadable and the compiler would be less able to detect
developer screw-ups. IOW, the 'T' is just syntactic sugar designed to
address the developer's problems of maintainability and fallibility
rather than the correctness of the solution.
I see. Well, it is a very retrograde view, I must say. But let's take it
for a while. It would just mean that you don't have pointer type as proper
type. That effectively closes any discussion about whether a non-type is a
subtype or not. Modern languages have proper pointer types. You can define
new operations on them, you can influence their representation etc. In this
case you cannot wave your hands - it is just a sugar. Because it is not.
Whether you need such things in your model is another question. Note
though, that assuming your sugar to always exist, heavily damages language
performance (prevents some valued optimizations) and plain wrong when you
dealing with things which semantically cannot be referenced (values in I/O
registers, clock readings, random generator realizations).
Foo can only be called on T.
That's Foo 1. Foo 2 can be called only on T*. Foo polymorphic can be called
on any (on one the class).
What?!? We seem to be on different planets again. If T* is pointing to
a T, then the only Foo available is the one on T. T* is just an
indirection mechanism to get to a T. One /never/ gets a different Foo
from accessing through T* than one gets by accessing directly from T.
See above. In my model T* and T are different types. You just cannot call
T::Foo on T*. It is no-no. So you call T*::Foo which is *implemented* as
pointer dereferencing followed by a call T::Foo.
If one could, one has Anarchy rather than an OOPL. B-)
One could! (:-)) You can define T*::Foo so that it would call T::Bar
instead. In any case, a reasonable implementation of T*::Foo would throw an
exception if the pointer is invalid.
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.
Maybe, but I don't want implicit assumptions. If T* is a side effect, then
one cannot talk about identity. If it is an intentional choice to achieve
identity, then that should be made explicitly.
Well, personally I much prefer the always-a-reference approach. It
leads to a lot less foot-shooting.
But it is fundamentally inconsistent with always-an-object approach. You
need things which aren't references. Reference itself is not reference. You
will lack too much reflection if you would try to pursue this approach it
its logical ends.
--
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
- 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
- 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):
Relevant Pages
|