A renewed call for interface methods with bodies

Yigal Chripun yigal100 at gmail.com
Sat Jan 26 01:15:43 PST 2008


Jesse Phillips wrote:
> On Fri, 25 Jan 2008 03:31:11 -0500, Burton Radons wrote:
>  
>> This has nothing to do with my proposal for interface methods with
>> bodies (that is, it works correctly whether or not this problem is
>> fixed), and I'm pretty sure the way it works now is a bug in the
>> compiler, since there's no justification for it acting that way. Again
>> and anon, my proposal does not modify overriding/overloading behaviour
>> at all. It would if you could also use override:
> 
> Please note that I'm not trying to say this is a bad thing to have, but 
> that it imposes the same problem that is inherent with multiple 
> inheritance. And I think the main point here is that the diamond problem 
> is not the sole conflict with multiple inheritance.
> 
> interface A {
>     void foo();
> }
> 
> interface B {
>     void foo() {
>         writefln("I am B");
> }   }
> 
> class C : A, B { }
> 
> void main() {
>     auto c = new C();
>     c.foo();
> }
> 
> You are claiming that your proposal just works without fixing the 
> problem. Well, here's the problem, what does c.foo() call? C is said to 
> have a function foo() because of A, which it does because of B. But in 
> your _solution_ A.foo() is not B.foo(). And yes, you have in-fact 
> provided a solution to the problem, which is you could not call c.foo(), 
> but instead have to call c.A.foo(). With which C would then have to 
> define void A.foo(){}; This I understand to be your solution to the 
> multiple inheritance problem. This only solves the diamond problem, but 
> not what is called by c.foo();
> 
> The current solution makes perfect sense as an interface is only there to 
> say that this class has the function, since the class implementing both A 
> and B has a void foo() then it has satisfied the claims of both. I 
> realize this can be a problem if A and B expect foo() to do something 
> completely different. But to this, I say redesign your class system.
> 
> Your suggestion really adds more complexity into building a simple 
> interface implementation. I would claim that this is worse merely because 
> the problem where two or more interfaces being imported with the same 
> function name being mutually exclusive is very rare (I could be wrong on 
> this).

I completely agree with the above, and want to add that such a case ( a 
diamond ) should be a compiler warning/error IMO.
You need to provide a foo method in the most derived class _with the 
override keyword_ and the compiler should complain if it's missing.
if you need a default implementation use mixins as others already mentioned.

no matter how many c++ programmers will complain the fact remains that 
MI is the wrong solution to the problem. inheritance does both 
sub-typing and sub-classing so D provides the proper solution of 
separating the two concepts. Interfaces provide sub-typing and mixins 
provide sub-classing.
so the proper solution IMO to implement MI like behavior is to do 
somthing like that:
---
interface A {
	void foo();
}
template A_impl {
	void foo() { ... }
}

interface B {
	void foo();
}
template B_impl {
	void foo() { ... }
}

class C : A, B {
mixin A_impl Ai;
mixin B_impl Bi;

alias Ai.foo fooA;
alias Bi.foo fooB;
}

void main() {
	auto test = new C();
	test.fooA();
	test.fooB();
}
---
I agree it's probably a bit more verbose than the c++ version but:
1) this situation is rare.
2) D provides a more flexible mechanism so the programmer has _more_ 
control over the process.
3) no need to mutilate the language or the compiler with a very complex 
MI implementation.

just my 2 euro cents

Yigal



More information about the Digitalmars-d mailing list