Re: Mixing OO and DB

From: Dmitry A. Kazakov <mailbox_at_dmitry-kazakov.de>
Date: Thu, 21 Feb 2008 13:11:33 +0100
Message-ID: <gy7y5a6mvdhx$.tr05iiwfrk53$.dlg_at_40tude.net>


On Wed, 20 Feb 2008 21:42:44 -0800 (PST), David BL wrote:

> On Feb 20, 8:05 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> wrote:

>> On Tue, 19 Feb 2008 18:15:31 -0800 (PST), David BL wrote:
>>> On Feb 19, 7:05 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
>>> wrote:
>>>> On Mon, 18 Feb 2008 19:09:48 -0800 (PST), David BL wrote:
>>>>> On Feb 19, 12:41 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
>>>>> wrote:
>>>>>> On Mon, 18 Feb 2008 05:59:39 -0800 (PST), David BL wrote:
>>>>>>> I disagree. I'm talking about algorithms that are implicitly
>>>>>>> parameterised over various value-types.  LSP isn't even applicable for
>>>>>>> value-types.
>>
>>>>>> How so? LSP defines behavioral notion of type as set of provable
>>>>>> predicates. This clearly includes your parametrized types. The parameters
>>>>>> are subjects of type substitution. It is pure LSP.
>>
>>>>> I have a more specific understanding of LSP.   Let an object mean a
>>>>> variable that has identity, state and behavior, but isn't assumed to
>>>>> hold a value.
>>
>>>> Wait here. Object's state + identity = its value. As I said before, value
>>>> semantics is fundamental in the sense that a stateful one is derived from
>>>> it.
>>
>>> Saying
>>
>>>     Object's state + identity = its value
>>
>>> doesn't seem well defined.  Does the object's state ever encompass
>>> following a pointer?   What about objects with OS resource handles
>>> like socket handles or mutex handles?  How do you delineate its state?
>>
>> Resource value /= value of its handle. They are of *different* types.

>
>> (You have a mental block about [fictional] equivalences of values. Whatever
>> equivalence between the resource and its handle might exist, it is not an
>> immanent thing. It is simply an implementation to be *first* proven to be
>> correct. Claiming the equivalence in advance is putting a cart before the
>> horse.)

>
> You didn't answer my question. How do you define an object's state
> when it contains pointers or handles?

Through the values of those pointers and handles. Where is a problem?

> Here's an example
>
> class X
> {
> public:
> X() { p = new int(0); }
> ~X() { delete p; }
> int Get() const { return *p; }
> void Set(int x) { *p = x; }
> private:
> int* p;
> };

And? Did you mean X could be made a subtype (and supertype) of int. So what?

>>>> Right, this is exactly what you said above "subtyping can mean
>>>> anything you want it to mean." It is not the compiler's business.
>>
>>> Can you define precisely what rules the compiler uses for
>>> substitutability?   Whatever the rules are, surely they are well
>>> defined?
>>
>> Yes. There rules are two:
>>
>> 1. It is typed: the value has to have the type expected.
>>
>> 2. S is a subtype of T in the operation f, if both types have this
>> operation defined.

>
> I thought we agreed type = set of values + operations. What does it
> mean to say an operation is defined?

It means that the type has this operation. Again subtyping is a relation to me. If + is defined on both T and S, then they are subtypes of each other.

>>>>> You are saying there is no difference in C.Date's notion of sub-
>>>>> typing, versus a definition of subtyping that allows you to substitute
>>>>> the type in a parameterisation.   I cannot understand that.
>>
>>>> We agree that type = values + operations. When we substitute a type, we do
>>>> its operations as well (where covariant). A simple consequence is that Z
>>>> which does not have Invert cannot be substituted where Invert operation is
>>>> expected. The notion of subtype is still same in the sense of conversions.
>>>> Date's subtype Z is R - Invert. He disallowed this operation. In some
>>>> contexts it will go, in others it will not.
>>
>>> On the contrary, Date assumes that Z inherits real-valued
>>> multiplicative inverses from R.   He doesn't disallow any operations.
>>> He states very clearly that a subtype always has a *superset* of the
>>> supertype's operations.
>>
>> This is sloppy. Remember that Invert is defined as:
>>
>>    Invert : T -> T
>>
>> When you say "inherit" you have to clarify where Z gets substituted. If you
>> substitute it only under the first T it is not an inheritance required for
>> a field. In effect the field's Invert is disallowed. The case is very
>> clear.

>
> C.Date made it very clear that subtyping (only) allows for value
> substitutability. I found nothing sloppy in his exposition.

Sloppiness is that this ignores other [useful] forms of substitution. I hope you aren't going discard the notion of field? Then how to capture it without out-substitutability?

Note that I don't buy parametrization for two reasons:

  1. It is a meta language (=accepted defeat)
  2. If parametrization were OK, then why did you introduce in-substitutability? Let's kill it too and use parametrization everywhere.
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Received on Thu Feb 21 2008 - 13:11:33 CET

Original text of this message