Re: Mixing OO and DB

From: David BL <davidbl_at_iinet.net.au>
Date: Thu, 14 Feb 2008 20:27:52 -0800 (PST)
Message-ID: <2c8d19ee-c646-4f95-9774-b6626d0933d3_at_e25g2000prg.googlegroups.com>


On Feb 15, 12:03 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de> wrote:
> On Thu, 14 Feb 2008 05:28:34 -0800 (PST), David BL wrote:
> > On Feb 14, 7:57 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> > wrote:
> >> On Wed, 13 Feb 2008 17:21:42 -0800 (PST), David BL wrote:
> >>> On Feb 14, 7:10 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> >>> wrote:
> >>>> On Tue, 12 Feb 2008 20:48:47 -0800 (PST), David BL wrote:
> >>>>> Objects are said to have identity, state and behavior. The idea that
> >>>>> an object can (always) be thought of as a (data) variable that can be
> >>>>> assigned a (data) value reveals a complete lack of understanding of
> >>>>> OO.
> >>>>> Bob's confusion between the concepts of object state versus object
> >>>>> value also leads him to misunderstand the significance of
> >>>>> encapsulation in the context of OO.
>
> >>>> I hate to agree with Bob Badour, but the notion of object is indeed
> >>>> superfluous. It is enough to have value, type, variable. Type has behavior.
> >>>> Variable has state. Identity can be attributed to a variable (the name of)
> >>>> or a value (the type of) or a type (the behavior of, or the name of, if
> >>>> named). What is specific to OO, that polymorphic values have identities of
> >>>> the corresponding specific types, which makes dispatch possible.
>
> >>> You appear to agree with Bob, but nothing could be further from the
> >>> truth.
>
> >>> Have you read the characterisations of value, variable and type by
> >>> C.Date? They are very different to your above descriptions.
>
> >>> value : doesn't exist in time or space. Immutable
> >>> variable : can be assigned a value
>
> >> Was it his wording? I don't remember. Or, maybe, "assigned" above is meant
> >> not as an operation defined, but rather as:
>
> >> variable : has a value
>
> > I checked C.Date's wording. He says a variable is a holder for the
> > appearance of a value, and a variable can be updated - meaning that
> > the current value of the variable can be replaced by another value.
>
> I don't think that it is essential for a variable to be replaceable.
> Consider a type over a set with exactly one value. Can I have a variable
> of? In my view variable is just a mapping of the computational state onto
> the set of values of the type.

Agreed.

> >>> type : set of values plus operations on those values
>
> >>> C.Date ignores the Liskov Substitution Principle (LSP) and states that
> >>> a circle is an ellipse, and that a coloured rectangle cannot be a
> >>> subtype of a rectangle.
>
> >> Well, circle is indeed an ellipse. It is just so that the implication
>
> >> circle is a ellipse => circle is substitutable for ellipse
>
> >> is wrong.
>
> > I think you need to qualify that. Using C.Date's definitions of type
> > and variable, a circle value is substitutable for an ellipse value,
> > whereas substitutability doesn't apply for variables.
>
> That makes the notion of subtype less interesting, especially if it would
> not apply to variables.

In a language that supports value-types properly, the following is useful

    float GetArea(Ellipse e);

    Circle c;
    float a = GetArea(c); // ok

GetArea() takes an ellipse by value, and one can happily provide a circle value (because every circle value is also an ellipse value).

Conversions of variables: With in-out parameters on functions no conversions are permitted. However with a pure out parameter we rightfully should support implicit upcast from address of ellipse variable to address of circle variable as follows

    // Assign a circle value to the variable with address c.     void AssignCircle(Circle* c);

    Ellipse e;
    AssignCircle(&e); // ok

That this is possible also follows from the fact that every circle value is also an ellipse value

> Further, the difference between values and
> variables is IMO not in immutability. Variable is an artefact of
> computation, a computational object. Value is outside, it is a semantic, a
> value of the object.

Agreed.

> > For an OO concept of type, substitutability of an object (ie
> > "variable") depends on whether the ellipse class provides any mutative
> > methods that could allow a circle object to stop being a circle.
>
> It is wider. It is about provable prepositions. Mutability is not an issue.
> One can express the problem without any mention of variables., fully
> immutably:
>
> forall x,y in R exists Ellipse with x=axis1 and y=axis2 (1)
>
> Circle is not substitutable here. But circle is still an ellipse in the
> sense of injective mapping:
>
> forall c of Circle exists e of Ellipse such that <no matter here> (2)
>
> 2 does not imply 1. End of story.

Agreed

> The actual problem is that for software
> design a notion of subtype based on 2 is uninteresting because it is the
> things like 1 we want to deal with.

This is often true, perhaps even mostly true, but not always true.

> Subtypes aren't subsets, because
> subsets are too weak to judge about substitutability.
>
> One cannot reduce subtypes to subsets, or wider behavior to data.

I see it slightly differently - that there are two distinct and incompatible notions of type. Both are important.

Consider the function 1/x which is axiomatically defined on (nonzero) reals but not the integers. That suggests that Z is not a subtype of R. However consider

    float Invert(float x) { return 1/x; }

That doesn't stop us calling Invert(2) even though 2 is only an integer. We still get a float result!

As another example, I think a language can rightly support implicit upcast of 16 bit integers to 32 bit integers. Of course we have to keep in mind that the modulo 2^16 operators are distinct from the modulo 2^32 operators.

> > It is interesting that if a language were to properly support value
> > types then we actually would want to *drop* state in derived classes
> > because specialisations give you less degrees of freedom, not more.
>
> I think it is interface inheritance from concrete type, is what you want.
>
>
>
>
>
> > I have wondered whether a language along the following lines would be
> > appropriate:
>
> > type Rect
> > {
> > int area { return width*height; }
> > int width;
> > int height;
> > };
>
> > type Square : Rect
> > {
> > int height { return width; }
> > };
>
> > type UnitSquare : Square
> > {
> > int width { return 1; }
> > };
>
> > void foo()
> > {
> > UnitSquare s;
> > int a = s.area;
> > }
>
> > I would hope that through in-lining the compiler simply initialises a
> > = 1.
>
> Yes, this is what I am arguing for years. This is exactly why there should
> be no such thing as "data" or "member." int width of the class rooted in
> Rect is pure behavior. It is incidentally implemented as a member (data)
> for the type Rect. That is an implementation detail, no more.

Yes, exactly.

I see it as only a convenience that one can specify the abstract interface and a possible implementation at the same time. Perhaps we need something like this

abstract type Point;

type CartesianPoint : Point
{

    float r { return sqrt(x*x + y*y); }
    float theta { return atan2(y,x); }
    float x,y;
};

type PolarPoint : Point
{

    float x { return r*cos(theta); }
    float y { return r*sin(theta); }
    float r, theta;
};

> Another
> implementation from the class (UnitSquare) could implement it differently.
> So it is only the contracted behavior "get width of," which matters.
>
> >> Further a coloured rectangle can be substitutable for rectangle
> >> in some context.
>
> > I think you need to qualify that as well, because now it's the
> > reverse: substitutability makes sense for variables, but not for
> > values!
>
> There are types of substitutability. You seem to call substitutability only
> in-substitutability (that is - to be substitutable in the operations taking
> in-arguments). But out-substitutability is of no less interests, as you
> have out, in-out arguments and results of operations.

I think when I say "substitutability of values" I mean what you call in-substitutability, and when I say "substitutability of variables" I mean what you call out-substitutability.

> > C++ programmers refer to the slicing problem when an upcast of a value
> > slices away some of its state. A coloured rectangle value can easily
> > have its colour sliced away.
>
> Which has to be this way. A colored rectangle value cannot be passed as a
> rectangle value, that would be a type error. It must be converted first.
> The result forgets anything it was before. As C.Date stays, values exist
> out of time, there is no any history of. So it has no color. The rest is a
> design fault of C++. It shall not dispatch on specific rectangle values.
> That breaks the contract of the corresponding type. One can dispatch on
> polymorphic values only.

Agreed.

> > I guess I need better words. Note however that I don't think
> > "behaviour" in the sense of conventional OO is relevant to value-
> > types. Values are immutable and all updates to variables are
> > assignments. A variable doesn't have a chance to exhibit behaviour!
> > At a certain level of abstraction all operators defined on a value
> > type can be assumed to act on pure inputs and return pure outputs.
>
> Yes. Just one note, values expose behavior of their type. The behavior of
> 1, an integer value, is in part that there exits 2, an integer value such
> that Inc(1)=2. Nothing beyond that. Behavior does not imply either
> statefulness or identity.

Yes. Received on Fri Feb 15 2008 - 05:27:52 CET

Original text of this message