Re: Mixing OO and DB

From: David BL <davidbl_at_iinet.net.au>
Date: Thu, 21 Feb 2008 19:00:41 -0800 (PST)
Message-ID: <e72f50ee-3c19-4d12-961a-14320a0ebf3d_at_p73g2000hsd.googlegroups.com>


On Feb 22, 4:04 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de> wrote:
> On Thu, 21 Feb 2008 05:41:42 -0800 (PST), David BL wrote:
> > On Feb 21, 9:11 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> > wrote:
> >> 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?
>

> > No. Please ignore the purpose of X. However assume that its copy
> > constructor and assignment operator have been declared private to make
> > it clear that it isn't a value type.
>

> > I wanted to establish what you considered the state of an object
> > instance to be. I presume it includes the value of the pointer p,
> > but not the int that p points at. Yes?
>

> Right, if we considered the private view of X, where p would be visible.
>

> > How do you justify that? It seems entirely adhoc to me.
>

> It is not very clear to me what does require a justification. There is no
> relation between X, int, int* except than stated. X has values. Note that
> values are incomparable (as it should follow from what I said before).
> Hence you could not say that two X are same if p is same. If we liked the
> compiler to copy X, we would declare corresponding copy operations. That
> would make possible by-copy parameter passing. But again it would not
> guarantee anything like "same value passed". The compiler would apply the
> copy operation, get a value and whether that is same is up to the
> programmer. In short, two values are same when the operation = is defined
> and returns true. Otherwise, nobody cares.

I see no point in thinking an object represents a value that combines its identity and state. It is a function of its implementation.

> >> I
> >> hope you aren't going discard the notion of field? Then how to capture it
> >> without out-substitutability?

>

> > Out-substitutability isn't enough either. Algorithms and data
> > structures that are parameterised in a field T may mention T in many
> > places. For example, in variables declared on the frame within a
> > function, or for members of data structures etc.
>

> You should care only of field operations.
>

> > I think it is utterly wrong to say that Real and Complex are subtypes
> > of Field. In fact I would suggest that it's rather confusing to think
> > of Field as a type at all!
>

> Sure, because field is a class, a set of types implementing the interface
> of. Note that class is not a type. A class can have an associated type of
> its polymorphic values when that makes sense. In the case of Real and
> Complex it does. I.e, there could be a subclass of field containing Real
> and Complex in order to be able to mix them in arithmetic. In general case
> for Field it does not make sense. It could be sort of:
>

> Field <-- Numeric field <--- Real / Complex
>

> > As we've agreed a type is a set of values
> > plus a set of operations on those values. Do you see how Field
> > doesn't fit that notion very well? If we want to shoehorn it into
> > being a type then its values are themselves types like Real and
> > Complex. I cannot think of any operations on it.
>

> Field is not a type it is a set { Real, Complex } (for simplicity only
> these two). The closure of Field is a proper type. Its values are pairs
> type - value. It has all operations of the field, like +, -, *, ... These
> operations are said dispatching (virtual in C++ terms). When + is applied
> to the polymorphic values an operation is chosen according to the first
> elements of the pairs involved and applied to the second elements of.

If you want a union type then it seems better to use an explicit supertype as per C.Date. In fact doing so makes it clear that the tag may not even be necessary - as when we want a common supertype of both Complex and Real, because Complex already serves that purpose if Real subtypes Complex.

> >> 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.
>

> > I don't accept your second reason because in-substitutability avoids a
> > lot of parameterisation so that's a positive not a negative.
>

> > In order to support a type of type like Field there needs to be
> > special syntactic support one way or the other. Perhaps something
> > like
>

> > // Field = set of types
> > type* Field;
>

> This is an interface. Here the field operations should be declared as
> abstract.
>

> > type Complex
> > in Field
> > {
> > ...
> > };
> > type Real
> > in Field
> > isa Complex
> > {
> > ...
> > };
>

> It is transitive, so Field need not to be mentioned here.
>

> > type* Ring;
>

> > type Integer
> > in Ring
> > isa Real
> > {
> > ...
> > };
>

> OK, but you should mention Ring interface in the Field one. Otherwise they
> will be different interfaces in Real. This is the diamond-diagram problem
> of multiple inheritance.
>

> > type Matrix<Field>
> > {
> > ...
> > };
>

> > Since we haven't been able to avoid parameterisation of Matrix,
>

> This is a different issue, namely, how containers are created in the types
> algebra. I would not like to see parametrization here. Instead it should
> state (without inventing some ad-hoc syntax):
>

> 1. Matrix is an interface
> 2. Matrix implements a container interface of a two dimensional array
> 3. The container elements are from the class of Field.
> 4. Matrix (square one) implements the ring interface
>

> Instead of parametrization Matrix could be constrained:
>

> 2.a in its indices (matrix size and shape)
> 3.a in its elements (real matrix, for instance)
>

> > I
> > don't think a lot has been achieved. Note as well that we didn't
> > actually formalise what a field is apart from stating that Real and
> > Complex are examples of fields.
>

> We did, when we declared Field. That shall have +, -, *, / etc. Real and
> Complex have to implement them. Matrix will use these operations in order
> to implement its own interface.

I think there is a danger that you will create a lot of effort for yourself (ie on top of a simple parameterisation approach). Received on Fri Feb 22 2008 - 04:00:41 CET

Original text of this message