www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'final' function implementations in interface definition

reply HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Hello,


Interface member functions do not have implementations. 
This specification prevents to implement macro-like small functions which won't
be overridden.
It seems that interfaces are possible to have function implementations if the
function is ensured not to be overridden.
Hence following list will possibly avoid problems in multiple inheritance.


interface I
{
	void f(int);
	final void f_twice(int i) { f(i); f(i); }
}

class C : I {...}

(new C).f_twice(1);



This list would be almost equivalent to another list



interface I
{
	void f(int);
}

void f_twice(I i, int n) { i.f(n); i.f(n); }

class C : I {...}

f_twice((new C), 1);
Jun 07 2009
next sibling parent reply Robert Clipsham <robert octarineparrot.com> writes:
HOSOKAWA Kenchi wrote:
 Hello,
 
 
 Interface member functions do not have implementations. 
 This specification prevents to implement macro-like small functions which
won't be overridden.
 It seems that interfaces are possible to have function implementations if the
function is ensured not to be overridden.
 Hence following list will possibly avoid problems in multiple inheritance.
 
 
 interface I
 {
 	void f(int);
 	final void f_twice(int i) { f(i); f(i); }
 }
 
 class C : I {...}
 
 (new C).f_twice(1);
 
 
 
 This list would be almost equivalent to another list
 
 
 
 interface I
 {
 	void f(int);
 }
 
 void f_twice(I i, int n) { i.f(n); i.f(n); }
 
 class C : I {...}
 
 f_twice((new C), 1);

If you want this then you need abstract classes. http://www.digitalmars.com/d/1.0/attribute.html#abstract abstract class A { abstract void f(int); final void f_twice(int i) { f(i); f(i); } } class B : A { } (new B).f_twice(1);
Jun 07 2009
parent reply HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Robert Clipsham Wrote:

 If you want this then you need abstract classes. 
 http://www.digitalmars.com/d/1.0/attribute.html#abstract
 
 abstract class A
 {
    abstract void f(int);
    final void f_twice(int i) { f(i); f(i); }
 }
 
 class B : A { }
 
 (new B).f_twice(1);

Unfortunately the derived class have already inherited another class in my code. I need interface inheritance.
Jun 07 2009
parent reply Robert Clipsham <robert octarineparrot.com> writes:
HOSOKAWA Kenchi wrote:
 Robert Clipsham Wrote:
 
 If you want this then you need abstract classes. 
 http://www.digitalmars.com/d/1.0/attribute.html#abstract

 abstract class A
 {
    abstract void f(int);
    final void f_twice(int i) { f(i); f(i); }
 }

 class B : A { }

 (new B).f_twice(1);

Unfortunately the derived class have already inherited another class in my code. I need interface inheritance.

You could use a template mixin then: template MyInterfaceMethods() { final void f_twice( int i ) { f(i); f(i); } } interface I { void f( int ); } class A : I { mixin MyInterfaceMethods; }
Jun 07 2009
parent HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Robert Clipsham Wrote:

 HOSOKAWA Kenchi wrote:
 Robert Clipsham Wrote:
 
 If you want this then you need abstract classes. 
 http://www.digitalmars.com/d/1.0/attribute.html#abstract

 abstract class A
 {
    abstract void f(int);
    final void f_twice(int i) { f(i); f(i); }
 }

 class B : A { }

 (new B).f_twice(1);

Unfortunately the derived class have already inherited another class in my code. I need interface inheritance.

You could use a template mixin then: template MyInterfaceMethods() { final void f_twice( int i ) { f(i); f(i); } } interface I { void f( int ); } class A : I { mixin MyInterfaceMethods; }

thanks for the solution but I think mixin is not better than global/final function. It requires to write mixin for each inherited classes, which usually increase binary size with duplicative function instances.
Jun 07 2009
prev sibling next sibling parent reply Steve Schveighoffer <schveiguy yahoo.com> writes:
On Sun, 07 Jun 2009 17:58:30 -0400, HOSOKAWA Kenchi wrote:

 Hello,
 
 
 Interface member functions do not have implementations. This
 specification prevents to implement macro-like small functions which
 won't be overridden. It seems that interfaces are possible to have
 function implementations if the function is ensured not to be
 overridden. Hence following list will possibly avoid problems in
 multiple inheritance.
 
 
 interface I
 {
 	void f(int);
 	final void f_twice(int i) { f(i); f(i); }
 }
 

f_twice can be a template: void f_twice()(int i) { f(i); f(i); } It's pretty much exactly what you want. It should even work without explicit instantiation. -Steve
Jun 07 2009
next sibling parent reply HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Steve Schveighoffer Wrote:

 
 f_twice can be a template:
 
 void f_twice()(int i) { f(i); f(i); }
 
 It's pretty much exactly what you want.  It should even work without 
 explicit instantiation.
 
 -Steve

I have tried to replace final function in the interface with your code. finally I got following message. Error: function I.f_twice!().f_twice template member function not allowed in interface I
Jun 07 2009
parent reply HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Steve Schveighoffer Wrote:

 On Sun, 07 Jun 2009 19:52:05 -0400, HOSOKAWA Kenchi wrote:
 
 Steve Schveighoffer Wrote:
 
 
 f_twice can be a template:
 
 void f_twice()(int i) { f(i); f(i); }
 
 It's pretty much exactly what you want.  It should even work without
 explicit instantiation.
 
 -Steve

I have tried to replace final function in the interface with your code. finally I got following message. Error: function I.f_twice!().f_twice template member function not allowed in interface I

I could have sworn I'd seen this or written something like this in tango's log package... It probably would be a good solution to this problem... -Steve

perhaps it is depends on the language version. At least both DMD 2.030 and 1.045 reject your suggestion. If the function is macro- or inline-type, there is no need to instantiate it into the interface definition. Your suggestion might be legal for the language design, I think.
Jun 07 2009
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
HOSOKAWA Kenchi Wrote:

 Steve Schveighoffer Wrote:
 
 On Sun, 07 Jun 2009 19:52:05 -0400, HOSOKAWA Kenchi wrote:
 
 Steve Schveighoffer Wrote:
 
 
 f_twice can be a template:
 
 void f_twice()(int i) { f(i); f(i); }
 
 It's pretty much exactly what you want.  It should even work without
 explicit instantiation.
 
 -Steve

I have tried to replace final function in the interface with your code. finally I got following message. Error: function I.f_twice!().f_twice template member function not allowed in interface I

I could have sworn I'd seen this or written something like this in tango's log package... It probably would be a good solution to this problem... -Steve

perhaps it is depends on the language version. At least both DMD 2.030 and 1.045 reject your suggestion.

I think possibly I compiled without instantiating the template, and that's why it worked...
 
 If the function is macro- or inline-type, there is no need to instantiate it
into the interface definition.
 Your suggestion might be legal for the language design, I think.

Templates do not go into the vtable, and are essentially final. So it would be a legal solution. It would also be nice to be able to have the ability to do templates in an interface. Your suggestion for final functions may also be a possible solution, but I see one caveat: If the function overrides a base-interface's non-final function, then the function has to go into the base-interface's vtable, which is probably not correct. -Steve -Steve
Jun 08 2009
parent HOSOKAWA Kenchi <hskwk inter7.jp> writes:
Steven Schveighoffer Wrote:

 perhaps it is depends on the language version.
 At least both DMD 2.030 and 1.045 reject your suggestion.


My code is here: interface I { void f(int); void f_twice()() { f(1); f(1); } } class C : I { void f(int i) { } } void main() { (new C).f_twice(); } For this code DMD said Error: function I.f_twice!().f_twice template member function not allowed in interface I I would like to know the code is proper for my purpose.
 Templates do not go into the vtable, and are essentially final.  So it would
be a legal solution.  It would also be nice to be able to have the ability to
do templates in an interface.
 
 Your suggestion for final functions may also be a possible solution, but I see
one caveat: If the function overrides a base-interface's non-final function,
then the function has to go into the base-interface's vtable, which is probably
not correct.

thanks for your explanation. my suggestion is not better because check code for the final function in the inherited interface make the compiler be complex, which violates D's policy.
Jun 08 2009
prev sibling parent Steve Schveighoffer <schveiguy yahoo.com> writes:
On Sun, 07 Jun 2009 19:52:05 -0400, HOSOKAWA Kenchi wrote:

 Steve Schveighoffer Wrote:
 
 
 f_twice can be a template:
 
 void f_twice()(int i) { f(i); f(i); }
 
 It's pretty much exactly what you want.  It should even work without
 explicit instantiation.
 
 -Steve

I have tried to replace final function in the interface with your code. finally I got following message. Error: function I.f_twice!().f_twice template member function not allowed in interface I

I could have sworn I'd seen this or written something like this in tango's log package... It probably would be a good solution to this problem... -Steve
Jun 07 2009
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-06-07 17:58:30 -0400, HOSOKAWA Kenchi <hskwk inter7.jp> said:

 interface I
 {
 	void f(int);
 	final void f_twice(int i) { f(i); f(i); }
 }
 
 class C : I {...}
 
 (new C).f_twice(1);

If you don't mind about the syntactic difference: interface I { void f(int); } void f_twice(I a, int i) { a.f(i); a.f(i; } class C : I {...} f_twice(new C, 1); -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jun 07 2009
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
HOSOKAWA Kenchi escribió:
 Hello,
 
 
 Interface member functions do not have implementations. 
 This specification prevents to implement macro-like small functions which
won't be overridden.
 It seems that interfaces are possible to have function implementations if the
function is ensured not to be overridden.

What about this? interface A { void foo(); final int fun() { return 1; } } interface B { void bar(); final int fun() { return 2; } } class C : B, A { } (new C).fun(); What does that do? I think this has the same problems as multiple inheritance.
Jun 07 2009
parent grauzone <none example.net> writes:
 What about this?
 
 interface A {
   void foo();
   final int fun() { return 1; }
 }
 
 interface B {
   void bar();
   final int fun() { return 2; }
 }
 
 class C : B, A {
 }
 
 (new C).fun();
 
 What does that do?

Simple: overriding final methods is illegal.
Jun 07 2009