www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [D.typesystem] Suggestion for improving OO inheritance models

reply Justin Johansson <no spam.com> writes:
Whilst one admirable aspiration of D is to make for better
meta-programming capability in a PL, IMHO one seemingly-lacking
aspiration of D is in the area of improving OO inheritance models
over and above that provisioned for in C++ and Java.

Maybe I'm ill-informed though I'd say that D, C++ and Java
more-or-less share the same OO inheritance model being that
of inheritance/derivation by extension as opposed to, say,
inheritance/derivation by restriction.  (Observation: Java
even uses the 'extends' keyword to introduce derived classes;
this hardly caters for inheritance by restriction).

May I suggest that a discussion ensure about a taxonomy of
OO inheritance models, including the notions of inheritance
by extension, restriction, code refactoring purposes etc.
so that D can evolve to a position to be able to claim a
higher moral plane over C++, Java, et al.

Cheers
Justin Johansson
Sep 01 2010
parent reply retard <re tard.com.invalid> writes:
Wed, 01 Sep 2010 23:16:15 +0930, Justin Johansson wrote:

 Whilst one admirable aspiration of D is to make for better
 meta-programming capability in a PL, IMHO one seemingly-lacking
 aspiration of D is in the area of improving OO inheritance models over
 and above that provisioned for in C++ and Java.
 
 Maybe I'm ill-informed though I'd say that D, C++ and Java more-or-less
 share the same OO inheritance model being that of inheritance/derivation
 by extension as opposed to, say, inheritance/derivation by restriction. 
 (Observation: Java even uses the 'extends' keyword to introduce derived
 classes; this hardly caters for inheritance by restriction).
 
 May I suggest that a discussion ensure about a taxonomy of OO
 inheritance models, including the notions of inheritance by extension,
 restriction, code refactoring purposes etc. so that D can evolve to a
 position to be able to claim a higher moral plane over C++, Java, et al.
Have you taken a loot at Scala & traits already? It would be a great starting point.
Sep 01 2010
parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:

 Have you taken a loot at Scala & traits already? It would be a great
 starting point.
Scala's traits are great! Implicits in Scala are quite interesting too. Also, Haskell typeclasses I wonder if D can have part of Scala traits functionality with mixins?
Sep 01 2010
parent reply Jacob Carlborg <doob me.com> writes:
On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:


     Have you taken a loot at Scala & traits already? It would be a great
     starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods. -- /Jacob Carlborg
Sep 01 2010
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
You mean like this?:
module add_virtual_functions;

import std.stdio : writeln;

void main()
{
    test();
}

mixin template Foo()
{
    void func()
    {
        writeln("Foo.func()");
    }
}

class Bar
{
    void func()
    {
        writeln("Bar.func()");
    }
}

class Code : Bar
{
    mixin Foo;
}

void test()
{
    Bar b =3D new Bar();
    b.func();   // calls Bar.func()

    Code c =3D new Code();
    c.func();   // calls Code.func()
}


On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg <doob me.com> wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:


 =A0 =A0Have you taken a loot at Scala & traits already? It would be a gr=
eat
 =A0 =A0starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existin=
g
 methods.


 --
 /Jacob Carlborg
Sep 01 2010
parent reply Jacob Carlborg <doob me.com> writes:
On 2010-09-01 23:39, Andrej Mitrovic wrote:
 You mean like this?:
 module add_virtual_functions;

 import std.stdio : writeln;

 void main()
 {
      test();
 }

 mixin template Foo()
 {
      void func()
      {
          writeln("Foo.func()");
      }
 }

 class Bar
 {
      void func()
      {
          writeln("Bar.func()");
      }
 }

 class Code : Bar
 {
      mixin Foo;
 }

 void test()
 {
      Bar b = new Bar();
      b.func();   // calls Bar.func()

      Code c = new Code();
      c.func();   // calls Code.func()
 }
No, that is overriding. Overloading is having several methods with the same name taking different number of parameters or parameters of different types. module test; mixin template Foo () { void bar (int i) {}; } class Bar { void bar () {}; mixin Foo; } void main () { auto bar = new Bar; bar.bar(4); // line 17 bar.bar(); } The above code results in these errors: test.d(17): Error: function test.Bar.bar () is not callable using argument types (int) test.d(17): Error: expected 0 arguments, not 1 for non-variadic function type void()
 On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg<doob me.com>  wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard<re tard.com.invalid>  wrote:


     Have you taken a loot at Scala&  traits already? It would be a great
     starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods. -- /Jacob Carlborg
-- /Jacob Carlborg
Sep 02 2010
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Yeah, my mistake. I missread your post. :)

But, you can use mixin expressions to add overloaded methods. E.g.:

import std.stdio;

class Bar
{
    void func()
    {
        writeln("Bar.func()");
    }

    mixin("void func(string x) { writeln(x); }");
}

void main()
{
    Bar bar =3D new Bar;
    bar.func();
    bar.func("test");
}

So I'm wondering if there could be an easy way to use mixin
expressions with mixin templates..

On Thu, Sep 2, 2010 at 10:17 AM, Jacob Carlborg <doob me.com> wrote:
 On 2010-09-01 23:39, Andrej Mitrovic wrote:
 You mean like this?:
 module add_virtual_functions;

 import std.stdio : writeln;

 void main()
 {
 =A0 =A0 test();
 }

 mixin template Foo()
 {
 =A0 =A0 void func()
 =A0 =A0 {
 =A0 =A0 =A0 =A0 writeln("Foo.func()");
 =A0 =A0 }
 }

 class Bar
 {
 =A0 =A0 void func()
 =A0 =A0 {
 =A0 =A0 =A0 =A0 writeln("Bar.func()");
 =A0 =A0 }
 }

 class Code : Bar
 {
 =A0 =A0 mixin Foo;
 }

 void test()
 {
 =A0 =A0 Bar b =3D new Bar();
 =A0 =A0 b.func(); =A0 // calls Bar.func()

 =A0 =A0 Code c =3D new Code();
 =A0 =A0 c.func(); =A0 // calls Code.func()
 }
No, that is overriding. Overloading is having several methods with the sa=
me
 name taking different number of parameters or parameters of different typ=
es.
 module test;

 mixin template Foo ()
 {
 =A0 =A0 =A0 =A0void bar (int i) {};
 }

 class Bar
 {
 =A0 =A0 =A0 =A0void bar () {};
 =A0 =A0 =A0 =A0mixin Foo;
 }

 void main ()
 {
 =A0 =A0 =A0 =A0auto bar =3D new Bar;
 =A0 =A0 =A0 =A0bar.bar(4); // line 17
 =A0 =A0 =A0 =A0bar.bar();
 }

 The above code results in these errors:

 test.d(17): Error: function test.Bar.bar () is not callable using argumen=
t
 types (int)
 test.d(17): Error: expected 0 arguments, not 1 for non-variadic function
 type void()


 On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg<doob me.com> =A0wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard<re tard.com.invalid> =A0wrote:


 =A0 =A0Have you taken a loot at Scala& =A0traits already? It would be =
a great
 =A0 =A0starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too=
.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods. -- /Jacob Carlborg
-- /Jacob Carlborg
Sep 02 2010
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Yeah, my mistake. I missread your post. :)

But, you can use mixin expressions to add overloaded methods. E.g.:

import std.stdio;

class Bar
{
    void func()
    {
        writeln("Bar.func()");
    }

    mixin("void func(string x) { writeln(x); }");
}

void main()
{
    Bar bar =3D new Bar;
    bar.func();
    bar.func("test");
}

So I'm wondering if there could be an easy way to use mixin
expressions with mixin templates..

On Thu, Sep 2, 2010 at 10:17 AM, Jacob Carlborg <doob me.com> wrote:
 On 2010-09-01 23:39, Andrej Mitrovic wrote:
 You mean like this?:
 module add_virtual_functions;

 import std.stdio : writeln;

 void main()
 {
 =A0 =A0 test();
 }

 mixin template Foo()
 {
 =A0 =A0 void func()
 =A0 =A0 {
 =A0 =A0 =A0 =A0 writeln("Foo.func()");
 =A0 =A0 }
 }

 class Bar
 {
 =A0 =A0 void func()
 =A0 =A0 {
 =A0 =A0 =A0 =A0 writeln("Bar.func()");
 =A0 =A0 }
 }

 class Code : Bar
 {
 =A0 =A0 mixin Foo;
 }

 void test()
 {
 =A0 =A0 Bar b =3D new Bar();
 =A0 =A0 b.func(); =A0 // calls Bar.func()

 =A0 =A0 Code c =3D new Code();
 =A0 =A0 c.func(); =A0 // calls Code.func()
 }
No, that is overriding. Overloading is having several methods with the sa=
me
 name taking different number of parameters or parameters of different typ=
es.
 module test;

 mixin template Foo ()
 {
 =A0 =A0 =A0 =A0void bar (int i) {};
 }

 class Bar
 {
 =A0 =A0 =A0 =A0void bar () {};
 =A0 =A0 =A0 =A0mixin Foo;
 }

 void main ()
 {
 =A0 =A0 =A0 =A0auto bar =3D new Bar;
 =A0 =A0 =A0 =A0bar.bar(4); // line 17
 =A0 =A0 =A0 =A0bar.bar();
 }

 The above code results in these errors:

 test.d(17): Error: function test.Bar.bar () is not callable using argumen=
t
 types (int)
 test.d(17): Error: expected 0 arguments, not 1 for non-variadic function
 type void()


 On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg<doob me.com> =A0wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard<re tard.com.invalid> =A0wrote:


 =A0 =A0Have you taken a loot at Scala& =A0traits already? It would be =
a great
 =A0 =A0starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too=
.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods. -- /Jacob Carlborg
-- /Jacob Carlborg
Sep 02 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Disregard the module name declaration. The original example had the
template mixin create a virtual method, and then you can override it
in the inheriting class.

On Wed, Sep 1, 2010 at 11:39 PM, Andrej Mitrovic
<andrej.mitrovich gmail.com> wrote:
 You mean like this?:
 module add_virtual_functions;

 import std.stdio : writeln;

 void main()
 {
 =A0 =A0test();
 }

 mixin template Foo()
 {
 =A0 =A0void func()
 =A0 =A0{
 =A0 =A0 =A0 =A0writeln("Foo.func()");
 =A0 =A0}
 }

 class Bar
 {
 =A0 =A0void func()
 =A0 =A0{
 =A0 =A0 =A0 =A0writeln("Bar.func()");
 =A0 =A0}
 }

 class Code : Bar
 {
 =A0 =A0mixin Foo;
 }

 void test()
 {
 =A0 =A0Bar b =3D new Bar();
 =A0 =A0b.func(); =A0 // calls Bar.func()

 =A0 =A0Code c =3D new Code();
 =A0 =A0c.func(); =A0 // calls Code.func()
 }


 On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg <doob me.com> wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:


 =A0 =A0Have you taken a loot at Scala & traits already? It would be a g=
reat
 =A0 =A0starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existi=
ng
 methods.


 --
 /Jacob Carlborg
Sep 01 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Ah nevermind. I didn't realize you've said "overload".

On Wed, Sep 1, 2010 at 11:39 PM, Andrej Mitrovic
<andrej.mitrovich gmail.com> wrote:
 You mean like this?:
 module add_virtual_functions;

 import std.stdio : writeln;

 void main()
 {
 =A0 =A0test();
 }

 mixin template Foo()
 {
 =A0 =A0void func()
 =A0 =A0{
 =A0 =A0 =A0 =A0writeln("Foo.func()");
 =A0 =A0}
 }

 class Bar
 {
 =A0 =A0void func()
 =A0 =A0{
 =A0 =A0 =A0 =A0writeln("Bar.func()");
 =A0 =A0}
 }

 class Code : Bar
 {
 =A0 =A0mixin Foo;
 }

 void test()
 {
 =A0 =A0Bar b =3D new Bar();
 =A0 =A0b.func(); =A0 // calls Bar.func()

 =A0 =A0Code c =3D new Code();
 =A0 =A0c.func(); =A0 // calls Code.func()
 }


 On Wed, Sep 1, 2010 at 11:30 PM, Jacob Carlborg <doob me.com> wrote:
 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:


 =A0 =A0Have you taken a loot at Scala & traits already? It would be a g=
reat
 =A0 =A0starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existi=
ng
 methods.


 --
 /Jacob Carlborg
Sep 01 2010
prev sibling parent reply retard <re tard.com.invalid> writes:
Wed, 01 Sep 2010 23:30:08 +0200, Jacob Carlborg wrote:

 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard <re tard.com.invalid> wrote:


     Have you taken a loot at Scala & traits already? It would be a
     great starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods.
I'm afraid D's template mixins are like a poor man's copy/paste macro system. Scala's approach takes subtyping into account. D 2 took a step towards traits actually since it allows some implementations & contracts in interfaces. However, Scala is more flexible. Scala's design had the focus on nice OOP properties the whole time, but D will probably only get features if implementing them efficiently is a low hanging fruit. One interesting feature in Scala are the types of objects in this case: class A {} trait T {} class B extends A with T {} val foo = (new B) : (A with T) -- I suppose D doesn't allow this: class A {} interface T {} class B : A, T {} (A & T) foo = new B In Scala the inheritance graph looks like: Any | AnyRef | Object | A ____ T | / A with T | B In D it's just: Object | A ____T | / B
Sep 01 2010
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 9/1/10 16:56 CDT, retard wrote:
 Wed, 01 Sep 2010 23:30:08 +0200, Jacob Carlborg wrote:

 On 2010-09-01 22:44, Philippe Sigaud wrote:
 On Wed, Sep 1, 2010 at 18:13, retard<re tard.com.invalid>  wrote:


      Have you taken a loot at Scala&  traits already? It would be a
      great starting point.


 Scala's traits are great! Implicits in Scala are quite interesting too.
 Also, Haskell typeclasses

 I wonder if D can have part of Scala traits functionality with mixins?
You can't use D template mixins to add methods that will overload existing methods.
I'm afraid D's template mixins are like a poor man's copy/paste macro system. Scala's approach takes subtyping into account. D 2 took a step towards traits actually since it allows some implementations& contracts in interfaces. However, Scala is more flexible. Scala's design had the focus on nice OOP properties the whole time, but D will probably only get features if implementing them efficiently is a low hanging fruit.
I agree. Traits are my favorite feature of Scala and probably the main modeling advantage that Scala has over D and other languages. A carefully designed feature for the win. Scala-style mixins aren't very difficult to implement for D, but I'm not sure if something like this would happen soon. Andrei
Sep 01 2010