Re: Mixing OO and DB

From: Dmitry A. Kazakov <mailbox_at_dmitry-kazakov.de>
Date: Fri, 15 Feb 2008 21:24:34 +0100
Message-ID: <1789yx2ba4gj9$.kz07tz5fqtvf$.dlg_at_40tude.net>


On Fri, 15 Feb 2008 08:46:54 -0800 (PST), David BL wrote:

> On Feb 15, 8:20 pm, "Dmitry A. Kazakov" <mail..._at_dmitry-kazakov.de>
> wrote:
>> On Thu, 14 Feb 2008 20:27:52 -0800 (PST), in
>
>>> 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!
>>
>> I think there is a confusion here. Note that invert as an operation deals
>> with a tuple float x float:
>>
>> Invert : float -> float
>>
>> Now, the question is where are you going to substitute ints?
>>
>> 1. In the first appearance of float
>> 2. In the second one (result)
>> 3. In both
>>
>> Depending on that Invert will become inheritable or not. I.e
>> substitutability is not only parameter mode depending, it also depends on
>> the concrete parameters too. (For the sake of genericity, results are
>> parameters.)
>
> I'm aware of the three conceivable options, but I'm quite clear in my
> mind that the system should only support the narrowing of in-
> parameters and widening of out-parameters.

It is an arbitrary constraint, worse is that it kills any algebraic operations.

>Therefore, as Invert() has
> been written (1) is the only option.

As a counterexample, consider C (complex) instead of Z.

> If you want option (3) then you
> need to explicitly write a parameterised function. Eg
>
> template <class T> T Invert(T x) { return 1/x; }
>
> However it seems inappropriate to allow Invert<int>().

From the language design point of view there is no any problem because the type system shall have different types for polymorphic and specific values. So you could declare Invert in either of four forms:

Invert : T -> T     (substitutes both)
Invert : class T -> T  (substitutes the result)
Invert : T -> class T  (substitutes the argument)
Invert : class T -> class T  (does not substitute)

> When C.Date talks about value substitutability he doesn't mean you can
> pick any function you like and substitute a sub-type in place of a
> super-type throughout the function.

Then it is worse, it is so that substitutability is not controlled by the type. If so, then how it is any better than just let the programmer to do what he wants?

> Doing so gives you a *distinct*
> function and the system is not allowed to guess that it is meaningful
> to do so. If you wanted this to be valid, then it would greatly
> restrict possible sub-typing relationships and that limits code
> reuse. In particular, it would no longer be possible to treat Z as a
> subtype of R.

(which is not, in LSP sense.)

> Probably some mathematicians would think that is
> sensible since the system Z doesn't inherit the axiom for existence of
> multiplicative inverses from R. However, I prefer the idea that
> algorithms are parameterised explicitly where appropriate, and only
> let the system perform implicit type conversions on in/out parameters
> or assignments.

This is too restricting to me. I prefer to be able to design algorithms without parametrization.

  1. Why should I specify the parameters if the types are already known to the system?
  2. Static only parametrization makes impossible to design a huge range of applications where types are known only to be constrained to certain class. Even where applicable it becomes extremely weird. Look at STL. It is a mess.
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Received on Fri Feb 15 2008 - 21:24:34 CET

Original text of this message