Re: Mixing OO and DB

From: Dmitry A. Kazakov <mailbox_at_dmitry-kazakov.de>
Date: Mon, 18 Feb 2008 16:41:40 +0100
Message-ID: <k92k29i0cq7h$.15qm3w3fmigq3.dlg_at_40tude.net>


On Mon, 18 Feb 2008 05:59:39 -0800 (PST), David BL wrote:

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

>> On Sun, 17 Feb 2008 19:12:50 -0800 (PST), David BL wrote:
>>> On Feb 16, 8:38 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
>>> wrote:
>>>> On Fri, 15 Feb 2008 17:45:16 -0800 (PST), David BL wrote:
>>>>> On Feb 16, 5:24 am, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
>>>>> wrote:
>>>>>> On Fri, 15 Feb 2008 08:46:54 -0800 (PST), David BL wrote:
>>
>>>>>>>Therefore, as Invert() has
>>>>>>> been written (1) is the only option.
>>
>>>>>> As a counterexample, consider C (complex) instead of Z.
>>
>>>>> Please provide more details. Are you alluding to covariant return
>>>>> types? ie
>>
>>>>> Complex Invert(Complex x);
>>>>> Real Invert(Real x);
>>
>>>> Yes. Covariant result for Real :> Complex inheritance is appropriate and
>>>> reasonable. But it is not for Real :> Integer. This is a mathematical fact,
>>>> rather than a property of some arbitrary types system. The problem is that
>>>> C is a field, Z is not. Thus the types system shall be able to capture what
>>>> behavior (mathematical structure in this case) you are going to inherit
>>>> upon derivation from R, a ring (for Z) or a field (for C). There is no way
>>>> to know it in advance, and if we restricted it to "all what R is", we would
>>>> get just another R.
>>
>>> I assume the notation T :> S means S is a subtype of T. I think you
>>> are suggesting (a definition of subtyping) that T :> S implies that
>>> for any algorithm, all occurrences of T can be replaced by S.
>>
>> This is a LSP notion.
> 
> 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.

(The real problem with LSP is that unconditional substitutability is all thinkable context is impossible.)

>>> However, then there would be no valid subtyping relationships between
>>> Z,R and C. For example, R :> C isn't valid because R is an ordered
>>> field whereas C is not. C :> R isn't valid because C is an
>>> algebraically closed field, whereas R is not. Z isn't a subtype of
>>> either R of C because Z isn't a field. Neither R or C is a subtype
>>> of Z because only Z has the property that its positive elements are
>>> well-ordered.
>>
>> Right. This is why I treat subtyping as mere a types relation such that an
>> operation gets inherited. Inheritance means no more than that the compiler
>> does not spill a type error and routinely applies appropriate conversions
>> of the arguments. The conversions are user-defined or compiler-generated.

> 
> That's not formal enough for me.   It sounds like sub-typing can mean
> anything you want it to mean.

Right, it has to be this way. If I want to make square a subtype of train traffic, it is my business. I should provide the implementations of the corresponding operations and that is.

>>> I would suggest what you're after is some concept of abstract value-
>>> types like "Ring" and "Field". I can see it could be useful to write
>>> data structures and algorithms in their most generic sense without
>>> explicit parameterisation. For example matrices are defined on an
>>> abstract field. This still allows for many nontrivial functions to be
>>> written - eg matrix inverse. I can imagine indicating that R,C are
>>> subtypes of Field according to this parameterisation notion of sub-
>>> type.
>>
>>> However independently of such as feature, I still believe it is
>>> important to capture the quite different concept of subtyping espoused
>>> by C.Date, because it concerns implicit conversions of value-types (as
>>> distinct from parameterisation), and that's very important.
>>
>> I see no difference. To me it is the same notion of subtyping.
>
> Really! I can't understand that.

I don't see how Date's conversions are any different from mine:

S is an in-subtype of T in the operation f iff:

  1. there exists f, operation on T denoted as T.f

   T.f : T -> <no matter>

2. there exists a conversion from S to T:

   S_to_T : S -> T

3. there exits f, operation on S denoted as S.f

   S.f : S -> <no matter>

It is said that f is inherited by S iff

   S.f = T.f o S_to_T

>>> Treating Z as a subset of R, or R as a subset of C is very useful. A
>>> function that accepts a complex number can be passed a real number
>>> without explicit conversion. A function that returns a real number
>>> can used to initialise a complex variable. Implicit conversions are
>>> deemed valid if and only if *exactly the same logical value* is
>>> represented before and after the "conversion". This implies two
>>> things: the conversion cannot silently drop information, nor can it
>>> silently add information.
>>
>> I would relax this too. Note that you can add exceptions as ideals to the
>> set of values. This gives you an opportunity to convert non-substitutable
>> out-Circle for out-Ellipse into substitutable
>> out-Circle-or-else-Constraint_Error for
>> out-Ellipse-or-else-Constraint_Error.
>
> Sorry, I just cannot understand your approach.

You cannot convert, you can drop an exception. This makes things substitutable back. This is not mine approach, it is a widely used model. Consider float. You cannot convert max float + max float from R back to float. So you throw overflow, or use NaN, whatsoever. You add an ideal to the set of floats /= R.

> You didn't answer my question: When a Rectangle value is converted to > a ColouredRectangle, what is the colour initialised to?

It cannot be converted! For out-substitutability of Rectangle, it is out ColouredRectangle which is converted to Rectangle.

In-substitutability of S to T in f() works as a composition f o S_to_T Out-substitutability of S to T in g() works as a composition S_from_T o g

The conversion is not forward, it backward.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Received on Mon Feb 18 2008 - 16:41:40 CET

Original text of this message