structs, classes, interfaces - Part III, Solution

Jari-Matti Mäkelä jmjmak at utu.fi.invalid
Sat Sep 1 05:20:44 PDT 2007


Martin Hinsch wrote:

> The basic idea behind my solution is actually really simple. You just have
> to realize that (OOP-) inheritance as it is usually done is a combination
> of two different concepts - composition and polymorphism. What would
> happen if we disentangled these concepts?
> 
> My suggestion would be to completely remove virtual functions from the
> language. Instead use interfaces to provide ad hoc runtime polymorphism.
> 
> As before interfaces define a set of methods a class has to provide. As
> before you can let a class derive from an interface to declare (and let
> the compiler check) its conformance to the interface. But now this is not
> obligatory anymore.

> I think this solves all problems I mentioned above except one, which is
> slicing. To be honest I never saw the particular danger in that one in the
> first place. Maybe I'm totally missing something but isn't that just
> another case of a lossy cast? In that case my proposal solves that problem
> as well since all potentially lossy (slicy ;-) casts can be detected at
> compile time and the user warned.
> 
> I have no illusions concerning the probability of this making it into D.
> Still I think it's a nice idea ;-) and I would be really interested in
> hearing what people think about it.

I'm not sure if I understood you correctly, but isn't this exactly the thing
that was discussed recently. From language consistency POV 

> class A {...}
> class B {...}
> 
> class C : A,B {...}

is a bit problematic because D doesn't have multiple inheritance. A trait
class construct could be possible though, but I cannot say if the added
complexity to the core language is good. However, the interface compliance
could be enforced that way (and Walter seems to like it too, see slides).
Implementation could be mixed in with an extended mixin syntax:

interface IA { void foo(); }
interface IB { int bar(); }

struct A : IA { void foo() { writefln("hello"); }
struct B : IB { int bar() { return 42; } }

struct C : IA, IB {
  mixin A;
  mixin B;
}

I've noticed mixin is a powerful mechanism. MI is more or less a combination
of interface part and mixed in implementation and provides a lot less
flexibility.



More information about the Digitalmars-d mailing list