Re: Mixing OO and DB
Date: Fri, 15 Feb 2008 12:13:33 +0100
Message-ID: <1nyb0fwzsdppy.9t9juzk8yvpo$.dlg_at_40tude.net>
On Fri, 15 Feb 2008 01:12:22 -0800 (PST), David BL wrote:
> On Feb 15, 1:27 pm, David BL <davi..._at_iinet.net.au> wrote:
>
>> 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.
>
> I take back my claim that "substitutability of variables" means out-
> substitutability. I think it should encompass both in-
> substitutability and out-substitutability.
>
> Therefore I was wrong to suggest that a pointer to a ColouredRectangle
> variable could be implicit cast to a pointer to a Rectangle variable,
> because it can lead to subsequent slicing.
An important node. Pointer is a data type distinct from the data type of
what it is supposed to point to. What you probably meant is that there
exists a mapping: f : ColouredRectangle -> Rectangle. Which in dreadful C++
notation looks like
*(Rectangle *)&
(a composition: &, casting and *). In a decent language, which C++ is not,
the operation * should not be allowed for all types indiscriminately. That
makes optimization quite difficult. What if Rectangle "physically exists"
on a different machine in a DB? How can I get its pointer? What is this
pointer? etc. Getting rid of data, also eliminates hard-wired data things
like pointers. Instead you get behavior of some objects referencing others.
> In the end it's better
> just to say that subtyping ColouredRectangle from Rectangle doesn't
> make sense and leave it at that.
But there exists a mapping between them, which makes possible for ColouredRectangle to be an extension of Rectangle. In practical terms it means that ColouredRectangle can be out-substitutable for Rectangle:
Give_Me_One : <something> -> Rectangle
(this case you considered for circle/ellipse later)
> If we go back to the much more sensible example of value-type
> inheritance of circle from ellipse we see that a circle is in-
> substitutable for an ellipse, whereas an ellipse is out-substitutable
> for a circle. That suggests to me that a language must distinguish
> out parameters from in-out parameters, and therefore passing out-
> parameters using pointers to variables isn't the right approach.
Sure. Note that out and by-reference are different issues. You can have copy-out passing for by-value types, and copy-in-copy-out for in-out ones. It is an implementation issue.
As for pointers, it is yet another story. T* can be considered as a subtype/supertype of T with all issues of substitutability. For instance, null is not substitutable in any of the operations of T.
> In the following example an ellipse is out-substitutable for a circle:
>
> // declaration
> Circle foo();
>
> // call
> Ellipse e = foo();
>
> I'm not sure I like this terminology of in-substitutable and out-
> substitutable. It seems easier to me to just remember that a circle
> value is an ellipse value and note that in-parameters narrow whereas
> out-parameters widen.
Ah, this is a crucial point. Circle value is not an ellipse value. These have different types. It is only so that there exists a mapping which gives you an ellipse value from any circle value.
> One of the reasons people tend to pass out parameters as pointer
> arguments is to support multiple out parameters. I rather like the
> idea of a language that supports a tuple syntax for multiple out
> parameters. Eg
>
> // definition
> (Circle c, int x) foo()
> {
> // Can assign named out-parameters c,x
> // No need for a 'return' statement!
> c = Circle( Point(0,0), 10 );
> x = 1;
> }
>
> // call
> (Ellipse e, int x) = foo();
Right. Anonymous ad-hoc types would make life a lot easier. But again, a tuple is a new type with all potential problems of substitutability. Same as with pointers, you might wish to consider (T) substitutable for T and reverse, for obvious reasons. Or maybe even (T, ...) for T, which would be in-substitutable of course. The problem is fundamental, and it does not have a universal solution, alas.
What the language should deliver is a clean types model.
As for subtyping, to me, it is just a relation between types. I don't expect it to deliver substitutability. It cannot. What it can and should, is to help me to deal with the problem.
-- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.deReceived on Fri Feb 15 2008 - 12:13:33 CET