www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Class and Interface Fun

reply John Reimer <terminal.node gmail.com> writes:
With this code:

--------------------------------

module test5;

interface I
{
    void foo();
}

class A : I 
{
    void foo() { }
}

class B : A, I
{
    alias A.foo foo;
}
    
void main()
{
}

--------------------------------

I get this error:

--------------------------------

class test5.B interface function I.foo is not implemented

--------------------------------

Does this make sense?  I mean, shouldn't the explicit reuse of A.foo in B 
be sufficient indication to the compiler that B is satisfying the contract 
I?   I'm hoping to make use of such subtleties in some code, but first I 
have to understand the reasoning behind this. :)

Note that this works if I remove the interface I from B's declaration -- 
ie "class B: A" -- since, in the D language, B is not required to fulfull 
A's interface contract even though it inherits from it. 

-JJR
Jan 24 2009
parent reply "Tim M" <a b.com> writes:
On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer <terminal.node gmail.com>  
wrote:

 With this code:

 --------------------------------

 module test5;

 interface I
 {
     void foo();
 }

 class A : I {
     void foo() { }
 }

 class B : A, I
 {
     alias A.foo foo;
 }
     void main()
 {
 }

 --------------------------------

 I get this error:

 --------------------------------

 class test5.B interface function I.foo is not implemented

 --------------------------------

 Does this make sense?  I mean, shouldn't the explicit reuse of A.foo in  
 B be sufficient indication to the compiler that B is satisfying the  
 contract I?   I'm hoping to make use of such subtleties in some code,  
 but first I have to understand the reasoning behind this. :)

 Note that this works if I remove the interface I from B's declaration --  
 ie "class B: A" -- since, in the D language, B is not required to  
 fulfull A's interface contract even though it inherits from it. -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Jan 24 2009
parent reply John Reimer <terminal.node gmail.com> writes:
Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 
 With this code:
 
 --------------------------------
 
 module test5;
 
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 
 I get this error:
 
 --------------------------------
 
 class test5.B interface function I.foo is not implemented
 
 --------------------------------
 
 Does this make sense?  I mean, shouldn't the explicit reuse of A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
 
 Note that this works if I remove the interface I from B's declaration
 --  ie "class B: A" -- since, in the D language, B is not required to
 fulfull A's interface contract even though it inherits from it. -JJR
 
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
Jan 24 2009
next sibling parent John Reimer <terminal.node gmail.com> writes:
Hello John,

 Hello tim,
 
 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 With this code:
 
 --------------------------------
 
 module test5;
 
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 I get this error:
 
 --------------------------------
 
 class test5.B interface function I.foo is not implemented
 
 --------------------------------
 
 Does this make sense?  I mean, shouldn't the explicit reuse of A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
 
 Note that this works if I remove the interface I from B's
 declaration --  ie "class B: A" -- since, in the D language, B is
 not required to fulfull A's interface contract even though it
 inherits from it. -JJR
 
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
Hmmm, now that I think of it... given the context of my question, I probably should have asked it in D newsgroup... -JJR
Jan 24 2009
prev sibling parent reply "Tim M" <a b.com> writes:
On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer <terminal.node gmail.com>  
wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
  Note that this works if I remove the interface I from B's declaration
 --  ie "class B: A" -- since, in the D language, B is not required to
 fulfull A's interface contract even though it inherits from it. -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
Jan 24 2009
next sibling parent John Reimer <terminal.node gmail.com> writes:
Hello tim,

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 
 Hello tim,
 
 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 With this code:
 --------------------------------
 module test5;
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 I get this error:
 --------------------------------
 class test5.B interface function I.foo is not implemented
 --------------------------------
 Does this make sense?  I mean, shouldn't the explicit reuse of
 A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in
 some
 code,  but first I have to understand the reasoning behind this. :)
 Note that this works if I remove the interface I from B's
 declaration
 --  ie "class B: A" -- since, in the D language, B is not required
 to
 fulfull A's interface contract even though it inherits from it.
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
Yes, I can resort to that if absolutely necessary (but I'd rather not :( ). I'm curious why doing a much simpler "alias" doesn't work, since it's the D way of making inherited methods accessible to the subclass. I figured that the "alias" should automatically (re-)implement the interface as well. -JJR
Jan 24 2009
prev sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
  Note that this works if I remove the interface I from B's declaration
 --  ie "class B: A" -- since, in the D language, B is not required to
 fulfull A's interface contract even though it inherits from it. -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
Jan 25 2009
next sibling parent reply "Tim M" <a b.com> writes:
On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin <2korden gmail.com>  
wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not required to
 fulfull A's interface contract even though it inherits from it. -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
Jan 25 2009
parent reply "Tim M" <a b.com> writes:
On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin <2korden gmail.com>  
 wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of  
 A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in some
 code,  but first I have to understand the reasoning behind this. :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not required  
 to
 fulfull A's interface contract even though it inherits from it. -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Jan 25 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin <2korden gmail.com>  
 wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of  
 A.foo
 in  B be sufficient indication to the compiler that B is satisfying
 the  contract I?   I'm hoping to make use of such subtleties in  
 some
 code,  but first I have to understand the reasoning behind this. :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not required  
 to
 fulfull A's interface contract even though it inherits from it.  
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the  
 class that implements I and B would implement it through inheritance or  
 you can to re implement I define all new implementations and put in  
 return super.foo(); where needed. It is also possible to reimplement one  
 interface function without re implementing the whole interface.
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
Jan 25 2009
parent reply "Tim M" <a b.com> writes:
On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin <2korden gmail.com>  
wrote:

 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin <2korden gmail.com>  
 wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of  
 A.foo
 in  B be sufficient indication to the compiler that B is  
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties in  
 some
 code,  but first I have to understand the reasoning behind this.  
 :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not  
 required to
 fulfull A's interface contract even though it inherits from it.  
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the  
 class that implements I and B would implement it through inheritance or  
 you can to re implement I define all new implementations and put in  
 return super.foo(); where needed. It is also possible to reimplement  
 one interface function without re implementing the whole interface.
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
Jan 25 2009
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 25 Jan 2009 15:20:19 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin <2korden gmail.com>  
 wrote:

 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin  
 <2korden gmail.com> wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of  
 A.foo
 in  B be sufficient indication to the compiler that B is  
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties in  
 some
 code,  but first I have to understand the reasoning behind this.  
 :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not  
 required to
 fulfull A's interface contract even though it inherits from it.  
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the  
 class that implements I and B would implement it through inheritance  
 or you can to re implement I define all new implementations and put in  
 return super.foo(); where needed. It is also possible to reimplement  
 one interface function without re implementing the whole interface.
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
No, I don't: class B : private A, public I { }
Jan 25 2009
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 25 Jan 2009 17:06:50 +0300, Denis Koroskin <2korden gmail.com> wrote:

 On Sun, 25 Jan 2009 15:20:19 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin <2korden gmail.com>  
 wrote:

 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin  
 <2korden gmail.com> wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer  
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:

 With this code:
  --------------------------------
  module test5;
  interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
  I get this error:
  --------------------------------
  class test5.B interface function I.foo is not implemented
  --------------------------------
  Does this make sense?  I mean, shouldn't the explicit reuse of  
 A.foo
 in  B be sufficient indication to the compiler that B is  
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties in  
 some
 code,  but first I have to understand the reasoning behind  
 this. :)
  Note that this works if I remove the interface I from B's  
 declaration
 --  ie "class B: A" -- since, in the D language, B is not  
 required to
 fulfull A's interface contract even though it inherits from it.  
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the  
 class that implements I and B would implement it through inheritance  
 or you can to re implement I define all new implementations and put  
 in return super.foo(); where needed. It is also possible to  
 reimplement one interface function without re implementing the whole  
 interface.
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
No, I don't: class B : private A, public I { }
Other example: interface IOStream : InputStream, OutputStream { } class A : InputStream { // implement InputStream } class B : A, IOStream { // implement OutputStream interface *only* } You can't define B like this: class B : A, OutputStream { ... } because this way it won't be castable to IOStream.
Jan 25 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
 [snip]

 B inherits all the functions from A implicitly. You stil may
 override any of the I interface functions if need be:

 class B : A, I
 {
      override void foo() { ... }
      // int bar() is inherited from A
 }

 Having B explicitly override all the base class virtual functions
 and forward them to A implementation just to make compiler happy is
 unintuitive and plain dumb to me.

 C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
No, I don't: class B : private A, public I { }
Other example: interface IOStream : InputStream, OutputStream { } class A : InputStream { // implement InputStream } class B : A, IOStream { // implement OutputStream interface *only* } You can't define B like this: class B : A, OutputStream { ... } because this way it won't be castable to IOStream.
I believe the rationale behind this is so that you can't implement an interface "by accident." For example, you might be implementing an interface, miss one method, and not know because the base class implements it. Alternately, you might be relying on such inheritance. Then, the base class changes, and you're left with compile errors and wondering why it doesn't work. Forcing you to specify each method removes this ambiguity from the code. That said, I could have SWORN that aliasing a method from the superclass worked. If this isn't a bug, it should be. Personally, yes it is a bit tedious, but this is why we have templates and mixins... -- Daniel
Jan 25 2009
parent John Reimer <terminal.node gmail.com> writes:
Hello Daniel,

 [snip]
 
 B inherits all the functions from A implicitly. You stil may
 override any of the I interface functions if need be:
 
 class B : A, I
 {
 override void foo() { ... }
 // int bar() is inherited from A
 }
 Having B explicitly override all the base class virtual functions
 and forward them to A implementation just to make compiler happy
 is unintuitive and plain dumb to me.
 
 C# allows that and I see absolutely no reason why D doesn't.
 
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
No, I don't: class B : private A, public I { }
Other example: interface IOStream : InputStream, OutputStream { } class A : InputStream { // implement InputStream } class B : A, IOStream { // implement OutputStream interface *only* } You can't define B like this: class B : A, OutputStream { ... } because this way it won't be castable to IOStream.
I believe the rationale behind this is so that you can't implement an interface "by accident." For example, you might be implementing an interface, miss one method, and not know because the base class implements it. Alternately, you might be relying on such inheritance. Then, the base class changes, and you're left with compile errors and wondering why it doesn't work. Forcing you to specify each method removes this ambiguity from the code. That said, I could have SWORN that aliasing a method from the superclass worked. If this isn't a bug, it should be. Personally, yes it is a bit tedious, but this is why we have templates and mixins... -- Daniel
Yes, that seems to be the reason. I actually want it to work the way it does, other than that I can't figure out why the aliasing doesn't work. The way it works now, I'm not forced to implement A's Interface if I only inherit from A. Explicit extension of a class with the same interface is necessary, and I /think/ this is the way it should be... but I'll lay claim to the "I'm not an expert" clause. :) -JJR -JJR
Jan 25 2009
prev sibling parent reply "Tim M" <a b.com> writes:
It not a bug though. It's all here  
http://www.digitalmars.com/d/1.0/interface.html and it works like it says.  
Is there a problem?
Jan 25 2009
parent John Reimer <terminal.node gmail.com> writes:
Hello tim,

 It not a bug though. It's all here
 http://www.digitalmars.com/d/1.0/interface.html and it works like it
 says.  Is there a problem?
 
The only thing that might be close to a bug, I think, is the inability of the "alias" to satisfy the interface contract reimplementation. -JJR
Jan 25 2009
prev sibling parent reply John Reimer <terminal.node gmail.com> writes:
Hello tim,

 On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin <2korden gmail.com>
 wrote:
 
 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:
 
 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:
 
 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin
 <2korden gmail.com>  wrote:
 
 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:
 
 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer
 <terminal.node gmail.com> wrote:
 
 Hello tim,
 
 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 With this code:
 --------------------------------
 module test5;
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 I get this error:
 --------------------------------
 class test5.B interface function I.foo is not implemented
 --------------------------------
 Does this make sense?  I mean, shouldn't the explicit reuse of
 A.foo
 in  B be sufficient indication to the compiler that B is
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties
 in
 some
 code,  but first I have to understand the reasoning behind
 this.
 :)
 Note that this works if I remove the interface I from B's
 declaration
 --  ie "class B: A" -- since, in the D language, B is not
 required to
 fulfull A's interface contract even though it inherits from
 it.
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the
 class that implements I and B would implement it through inheritance
 or  you can to re implement I define all new implementations and put
 in  return super.foo(); where needed. It is also possible to
 reimplement  one interface function without re implementing the
 whole interface.
 
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
What do you mean? In your example above, B does not have to implement the interface I of A. What do you mean by "interfaces become implicit"? -JJR
Jan 25 2009
parent reply "Tim M" <a b.com> writes:
On Mon, 26 Jan 2009 04:58:57 +1300, John Reimer <terminal.node gmail.com>  
wrote:

 Hello tim,

 On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin <2korden gmail.com>
 wrote:

 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:

 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin
 <2korden gmail.com>  wrote:

 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:

 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer
 <terminal.node gmail.com> wrote:

 Hello tim,

 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 With this code:
 --------------------------------
 module test5;
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 I get this error:
 --------------------------------
 class test5.B interface function I.foo is not implemented
 --------------------------------
 Does this make sense?  I mean, shouldn't the explicit reuse of
 A.foo
 in  B be sufficient indication to the compiler that B is
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties
 in
 some
 code,  but first I have to understand the reasoning behind
 this.
 :)
 Note that this works if I remove the interface I from B's
 declaration
 --  ie "class B: A" -- since, in the D language, B is not
 required to
 fulfull A's interface contract even though it inherits from
 it.
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as the
 class that implements I and B would implement it through inheritance
 or  you can to re implement I define all new implementations and put
 in  return super.foo(); where needed. It is also possible to
 reimplement  one interface function without re implementing the
 whole interface.
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
What do you mean? In your example above, B does not have to implement the interface I of A. What do you mean by "interfaces become implicit"? -JJR
I mean it will still have the foo function and you dont have to put anything on B to make it work: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A { } void main() { B b = new B; b.foo(); //this works }
Jan 25 2009
parent John Reimer <terminal.node gmail.com> writes:
Hello tim,

 On Mon, 26 Jan 2009 04:58:57 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 
 Hello tim,
 
 On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin
 <2korden gmail.com> wrote:
 
 On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a b.com> wrote:
 
 On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a b.com> wrote:
 
 On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin
 <2korden gmail.com>  wrote:
 
 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:
 
 On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer
 <terminal.node gmail.com> wrote:
 Hello tim,
 
 On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
 <terminal.node gmail.com>  wrote:
 With this code:
 --------------------------------
 module test5;
 interface I
 {
 void foo();
 }
 class A : I {
 void foo() { }
 }
 class B : A, I
 {
 alias A.foo foo;
 }
 void main()
 {
 }
 --------------------------------
 I get this error:
 --------------------------------
 class test5.B interface function I.foo is not implemented
 --------------------------------
 Does this make sense?  I mean, shouldn't the explicit reuse
 of
 A.foo
 in  B be sufficient indication to the compiler that B is
 satisfying
 the  contract I?   I'm hoping to make use of such subtleties
 in
 some
 code,  but first I have to understand the reasoning behind
 this.
 :)
 Note that this works if I remove the interface I from B's
 declaration
 --  ie "class B: A" -- since, in the D language, B is not
 required to
 fulfull A's interface contract even though it inherits from
 it.
 -JJR
It look like the real bug is re-allowing B to implement interface I but sometimes bug do get reported differently. Why don't you remove I from B's declaration like you said that works. It actually says here http://www.digitalmars.com/d/1.0/interface.html "Classes cannot derive from an interface multiple times."
Yes, please check the link again (further down the page). D allows you to reimplement the interface as long as class B provides a new implementation: "A reimplemented interface must implement all the interface functions, it does not inherit from a super class"... That probably could be stated a little more clearly, but that's what it says. As for why I'm doing it, I assure you that there's a very specific reason why I'm trying this: it is a possible interfacing mechansim for ported software of a much more complicated nature than this simple reduction; I reduced it to this in order to try to understand potential iteractions between class and interface layers. The question here was to figure out the reasoning behind the language design, not necessarily whether I should be doing it or not. ;-) -JJR
This works btw: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A,I { void foo() { A.foo(); } } void main() { }
It is too verbose and makes twice an overhead. I'd like to avoid this solution. In fact, I believe that class B : A, I {} should just work.
why? I think it is perfect how it is. You can either leave A as the class that implements I and B would implement it through inheritance or you can to re implement I define all new implementations and put in return super.foo(); where needed. It is also possible to reimplement one interface function without re implementing the whole interface.
If you are really needing to write least code you could also do something like this but not very nice to read: module test; template II(char[] func) { const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~ "() { return super." ~ func ~ "(); }" ; } interface I { void foo(); int bar(); } class A : I { void foo() { } int bar() { return 1; } } class B : A,I { //void foo() { return super.foo(); } mixin(II!("foo")); mixin(II!("bar")); } void main() { }
Not only I want to write less, I want my code be cleaner and run faster.
 why? I think it is perfect how it is. You can either leave A as
 the class that implements I and B would implement it through
 inheritance or  you can to re implement I define all new
 implementations and put in  return super.foo(); where needed. It
 is also possible to reimplement  one interface function without re
 implementing the whole interface.
 
That what /my/ solution do. class B : A, I {} is *absolutely* same as class B : A, I { override void foo() { super.foo(); } override int bar() { return super.bar(); } } Except that when you call B.foo, there is no damn double virtual function call. B inherits all the functions from A implicitly. You stil may override any of the I interface functions if need be: class B : A, I { override void foo() { ... } // int bar() is inherited from A } Having B explicitly override all the base class virtual functions and forward them to A implementation just to make compiler happy is unintuitive and plain dumb to me. C# allows that and I see absolutely no reason why D doesn't.
I think you are missing somethinghere. Change the B definition from: class B : A, I to just: class B : A then interfaces become impicit.
What do you mean? In your example above, B does not have to implement the interface I of A. What do you mean by "interfaces become implicit"? -JJR
I mean it will still have the foo function and you dont have to put anything on B to make it work: module test; interface I { void foo(); } class A : I { void foo() { } } class B : A { } void main() { B b = new B; b.foo(); //this works }
Oops. You are right. I missed that. I got this mixed up with overload rules. Thanks. "alias" is used in the subclass to /overload/ a method with super class ones. Unfortunately, because my assumptions were askew, I've got to retrace my steps. It's good this stayed in learn, afterall. :D Still, on the case of interface re-implementation, it would be nice if using the "alias" would work as I previously specified, though there are certainly workarounds available, if necessary. -JJR
Jan 25 2009
prev sibling parent Christopher Wright <dhasenan gmail.com> writes:
Denis Koroskin wrote:
 On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a b.com> wrote:
 class B : A,I
 {
     void foo() { A.foo(); }
 }
   void main()
 {
 }
It is too verbose and makes twice an overhead. I'd like to avoid this solution.
Any reasonable compiler would inline the call to A.foo.
 In fact, I believe that class B : A, I {} should just work.
I think that's something like checked exceptions: a wonderful idea in small examples, but it can cause problems in larger bodies of code. I haven't ever encountered this problem, but I've heard about it twice, I think, so maybe my coding is just a bit simpler than other people's.
Jan 25 2009