Re: Mixing OO and DB

From: Dmitry A. Kazakov <mailbox_at_dmitry-kazakov.de>
Date: Tue, 19 Feb 2008 10:42:43 +0100
Message-ID: <1tddtrcvj30kt.1f4ox2ud10w2m$.dlg_at_40tude.net>


On Mon, 18 Feb 2008 17:44:58 -0800 (PST), David BL wrote:

> On Feb 19, 12:41 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> wrote:

>> How can you implement integer if you don't know endianness?  It is nice to
>> talk about logical views as long there is a hardware that implements them.
>> But any hardware deals with a representation. A logical model just does not
>> stand the trivial requirement to be able to describe itself.

>
> Think of it this way... A string class defines both
>
> 1) an interface (with well defined contracts on the operators); and
>
> 2) an implementation (which defines both a physical representation as
> well as an implementation of all the operators that fullfills the
> documented interface).
>
> Do you agree that it is meaningful to think of these aspects as
> distinct, and somewhat independent?

Yes. Moreover this implies that we have to keep the values of the kinds 1 and 2 distinct. The values of the kind 1 are abstract strings, it can be any concrete implementation of string. They are said polymorphic. The values of the kind 2 are ones of a specific string type. When we talk about a string value we have to decide is it 1 or 2 (that implements 1).

> For example, assuming design by
> contract it is possible to change the implementation without changing
> the interface.

Yes. Precisely it means that you can program things in the terms of the kind 1 and substitute any kind 2 when you will.

> You seem to be thinking type = class,

No. To me class is a set of types. For some classes, like those built upon derivation, there exist special types of polymorphic values.

> whereas I'm thinking of type as
> by definition only relating to the public interface. More formally a
> value type is a set of values plus operations on those values.

Yes, of course.

> It is
> divorced from a particular implementation.

No. Each type has an implementation and this implementation is concrete. It only appears that you can change implementation. Substitution is a vehicle for. You substitute a string for its class. Both have implementations. BTw, when you substitute for a class, you convert its value:

   "abcd" --> (Four_Characters_UF8_Encoded_String, "abcd")

> In fact it is extremely important to understand that the same
> (logical) value can be encoded in different ways within the same
> program. For example a UnitSquare value can be encoded in a manner
> suitable for arbitrary quadrilaterals, or for rectangles, for squares
> or else very specifically for a unit square.

Yes. This is the requirement we both want to achieve. The difference is though, that in my system "logical values" become a part of the system. I can describe them and handle them in the language. This has no disadvantages for you, as you can still treat them as God-given things outside the system. So it covers your model as well.

>>> Are you suggesting there can be any number of levels of equivalence
>>> classes at ever increasing logical levels?
>>
>> Why not?

>
> A value-type is by definition a set of values plus operators on those
> values. There can only be one concept of equivalence for a given
> value-type.

Ugh, isn't 1 real, integer, complex, file descriptor number, character... I don't want to define equivalences in the language, it is the programmer's business. Formally, you can take some specific type with its values and put it in whatever class (by implementing the corresponding interface).

> A starting point is to have a very simple and clear understanding of
> "type".

Values + operations. I think we agree on that.

>>> I want to do the
>>> reverse which is more like design.  My approach is more restrictive -
>>> but IMO for good reasons.
>>
>>> I suggest a value type is by definition a set of (logical) values plus
>>> operators on those values.  There is no such thing as "physical
>>> values".   When a programmer defines a concrete type it is necessary
>>> to provide at least one physical implementation.  I have generally
>>> been ignoring that in all our discussions about value-types and sub-
>>> typing.   A physical representation is generally something to be
>>> hidden away, so that users of the type deal with it *only* at the
>>> logical level.  Users can specify values and use all the operators,
>>> including the test for value equivalence.  There can only be one
>>> definition of equivalence of values of a given type.  If another
>>> notion of value equivalence is required then a distinct type must be
>>> defined.
>>
>> I don't see how this could work. You will need some set of built-in pure
>> "logical" types which representation cannot be described. This is
>> unsatisfactory, because there will be no way to validate an implementation
>> of your logical hardware against the specifications. There actually will be
>> no specifications. Another problem is that I don't want any built-in types,
>> at least as little of them as possible.

>
> Yes there will be built in value types. Eg 32 bit integers. These
> have well defined semantics. All the programmer needs to know is that
> they map very directly and efficiently to the hardware. Little
> versus big endian encoding is irrelevant to the logical level semantic
> of the type.

As for modular types:

  1. may I have one of modulus 2**100000000000000000?
  2. how to write a (one) program which reads a modular integer value from the keyboard?
  3. note that "well defined semantics" contradicts to very definition of type:

   type = values + operations

So any subprogram taking a type value as a parameter is an operation => you cannot define semantics well. The only definition could be "all possible programs with the values of."

> Why do you think built-in value types are a problem? I believe they
> should be treated like any other type, apart from a user defined
> implementation being optional. For example, built-in types should
> take part in the type hierarchies.

Huh, what about integers, floats, fixed point? The semantics of those is *far* from being simple.

>>>> Note that this is same as in mathematics where Q
>>>> "contains" Z, while members of Q aren't numbers at all, but sets of ordered
>>>> pairs
>>
>>> Z is only uniquely defined up to isomorphism.  I think that explains
>>> why Q can be defined as sets of ordered pairs and yet contains Z.
>>
>> So what is wrong with handling values this way? Why isomorphism of little
>> endian to big endian numbers is worse? Why do you want to have some other
>> level behind it? My approach looks much simpler.

>
> I'm not sure what you are saying - you need to elaborate.

Let have two types IntBig and IntLittle. There is an isomorphism between the values of. If the compiler would apply it I could substitute one for another.

>>>> If you want to have classes of values, these will be polymorphic values,
>>>> which shall dispatch. Consider:
>>
>>>> class Boolean
>>>> {
>>>> public :
>>>>    virtual String Image () // returns "true"  or "false"
>>
>>>> };
>>
>>>> class Tristate : public Boolean
>>>> {
>>>> public :
>>>>    virtual String Image (); // returns "true", "false", "unknown"
>>
>>>> };
>>
>>> I'm afraid this gives me more questions than answers!  I don't know
>>> what a Boolean actually is.  Can it have 3 states?
>>
>> No, Boolean is defined over {0, 1}. Tristate is derived from it and is
>> defined over {0, 1, _|_}

>
> I don't understand the semantics of sub-typing in this case. Can a
> TriState value be implicit converted to a Boolean value? If so what
> happens when it's in the unknown state?

It cannot be. It is only out-substitutable. That means for example that Image has to be overridden. If inherited it will break the contract.

The compiler can immediately detect this, provided that Tristate would not inherit Boolean's implementation. There will be no default conversion Tristate -> Boolean, so the compiler will not be able to compose an inherited Image out of Boolean's Image and the type conversion. So it will complain. Note this is absolutely free on any black magic logical-values stuff. The compiler need not to know the semantics of Boolean in order to decide that.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Received on Tue Feb 19 2008 - 10:42:43 CET

Original text of this message