February 08, 2009
On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:


> In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types.

In D, what is the recommend technique to derive one user-defined value type from another?

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
February 08, 2009
Derek Parnell wrote:
> On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:
> 
> 
>> In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types.
> 
> In D, what is the recommend technique to derive one user-defined value type
> from another?

There isn't one. Deriving types only makes sense when expecting polymorphic behavior, which is completely orthogonal to the whole idea of a value type. A polymorphic type should be a reference type.

A value type can have *aggregation*, however, as in:


struct Sbase
{
    ... base members ...
}

struct S
{
    Sbase base;
    ... more members ...
}

You can also embed interfaces in a struct:

interface I { ... }
struct S
{
    I i;
}
February 08, 2009
On Sun, 08 Feb 2009 14:37:18 -0800, Walter Bright wrote:

> Derek Parnell wrote:
>> On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:
>> 
>>> In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types.
>> 
>> In D, what is the recommend technique to derive one user-defined value type from another?
> 
> There isn't one. Deriving types only makes sense when expecting polymorphic behavior, which is completely orthogonal to the whole idea of a value type. A polymorphic type should be a reference type.

Thank you. I was using "derive" in the English language sense rather than the O-O sense, but I get your point - for example a 'currency' value type is only ever to be used as a currency value and not any of its base value types.

Fair enough.


> A value type can have *aggregation*, however, as in:
> 
> struct Sbase
> {
>      ... base members ...
> }
> 
> struct S
> {
>      Sbase base;
>      ... more members ...
> }
>
> You can also embed interfaces in a struct:
> 
> interface I { ... }
> struct S
> {
>      I i;
> }

This is what I thought too. In D, a value type can be derived from another value type by using a combination of data aggregation (data inheritance if you will) and interface aggregation (method inheritance?).

I feel that D could do with a little more syntax support for derived value types though, because at times it is a bit awkward and/or verbose. I'll dig up some examples of what I mean.

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
February 08, 2009
Walter Bright wrote:
> Derek Parnell wrote:
>> On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:
>>
>>
>>> In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types.
>>
>> In D, what is the recommend technique to derive one user-defined value
>> type
>> from another?
> 
> There isn't one. Deriving types only makes sense when expecting polymorphic behavior, which is completely orthogonal to the whole idea of a value type. A polymorphic type should be a reference type.
> 

So far I am seeing that the slicing problem arises from the ability to place extra data into derived types.  But what of method inheritance?

It seems that something like this could work:

scope class A
{
	int x, y;
	int foo() { etc... }
}

class B : A
{
	// More data members are now forbidden.
	int foo() { etc... }
	void bar(char[] baz) {...}
}

struct S
{
	// in-place allocation
	scope A qux;
	scope A quux;
}

void main()
{
	S s;
	s.qux = new B;
}
February 08, 2009
On Mon, 09 Feb 2009 01:24:34 +0300, Derek Parnell <derek@psych.ward> wrote:

> On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:
>
>
>> In particular, classes are *meant* to be used as reference types, but
>> the program is trying to treat them as value types. Virtual functions
>> are orthogonal to what value types are - a continuing problem C++
>> programs have is conflating value types with reference types.
>
> In D, what is the recommend technique to derive one user-defined value type
> from another?
>

A mixin, perhaps:

struct Brush
{
   // ...
}

struct ColoredBrush
{
   mixin Brush;

   Color color;
}

February 09, 2009
== Quote from Derek Parnell (derek@psych.ward)'s article
> This is what I thought too. In D, a value type can be derived from another
> value type by using a combination of data aggregation (data inheritance if
> you will) and interface aggregation (method inheritance?).
> I feel that D could do with a little more syntax support for derived value
> types though, because at times it is a bit awkward and/or verbose. I'll dig
> up some examples of what I mean.

In D2, you could try aggregation and opDot() w/ ref return.  See http://digitalmars.com/d/2.0/operatoroverloading.html#Dot .  That pretty much simulates a form of inheritance w/o polymorphism.

struct Foo {
    int i;

    void doStuff() {
        // Do stuff.
    }
}

struct Bar {
    private Foo foo;

    ref Foo opDot() {
        return foo;
    }
}

void main() {
    Bar bar;
    bar.doStuff();  // Calls Bar.foo.doStuff().
}

One caveat, though, is that operator overloading behaves weirdly w/ this.  See bug 2327:  http://d.puremagic.com/issues/show_bug.cgi?id=2327
February 09, 2009
Derek Parnell wrote:
> On Sun, 08 Feb 2009 11:13:00 -0800, Walter Bright wrote:
> 
> 
>> In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types.
> 
> In D, what is the recommend technique to derive one user-defined value type
> from another?
> 

Go to the future and use the alias this thingie.

Andrei
February 09, 2009
Denis Koroskin пишет:

> And here are results (best/average of 3 runs):
> 
> DMD2.023 - 12.492/12.576 ms (-O -inline)
> DMC8.42n - 13.941/14.131 ms (-O -inline)
> 
> 

Try to return from value() a class instance
February 09, 2009
Weed Wrote:
> Denis Koroskin �����:
> 
> > And here are results (best/average of 3 runs):
> > 
> > DMD2.023 - 12.492/12.576 ms (-O -inline)
> > DMC8.42n - 13.941/14.131 ms (-O -inline)
> > 
> > 
> 
> Try to return from value() a class instance

In this case both C++ and D performance drops almost tenfold.
February 09, 2009
naryl пишет:
> Weed Wrote:
>> Denis Koroskin яПНяПНяПНяПНяПН:
>>
>>> And here are results (best/average of 3 runs):
>>>
>>> DMD2.023 - 12.492/12.576 ms (-O -inline)
>>> DMC8.42n - 13.941/14.131 ms (-O -inline)
>>>
>>>
>> Try to return from value() a class instance
> 
> In this case both C++ and D performance drops almost tenfold.

Hmmm. Can you show code?