Lutger wrote:

Ok, I sort of assumed you talked about explicit instantiation like in C#. For any type that implements a clone operation for example, you have to derive it from ICloneable if you are to use it as a generic parameter. In addition, in your template, you have to explicitly bring all operations under in an interface. (This is the bloat part). Now say I have a type from another library that supports cloning, has the same interface as ICloneable, but doesn't derive from it. You are forced to create a wrapper for it that derives from ICloneable. (the workaround). Also, there is the complication of what to do with arithmetic types.


the arithmetic types issue is not a problem in D since the relevant operators are non-static in D.
I don't understand what's the bloat here. here's an example:

interface I {  // you mean this interface is bloat ?
 void func() ;
}

class C(T : I) {
...
}

regarding the workaround issue, we agreed already that verifying a type against a concept is done structurally. possible solutions are that identical concepts with different names are implicitly castable to each other. the compiler will treat it similar to aliases.

suppose that you got a type implementing the MyClonable interface which is structurally identical to the standard ICloneable interface.
void foo(T : ICloneable) (T t) {...}
foo() should work with your type because for the compiler both interfaces represent the same concept.

this restricts "duck-typing" to the concept level only.
another option is that instead of this being done by the compiler, the programmer could specify this relation by:

alias MyConcept Iconcept;
// compile type-checks here for conformance and registers this identity

This idea probably can be further refined. I think My general direction here is to have C++ concepts but with a *much* better syntax and more tightly integrated into the type system. In C++ it feels like an optional addon added as an after thought.

Reply via email to