Don Wrote:
> > The way I see it we have three options:
> > 
> > assume we have these definitions:
> > interface I {...}
> > class Foo : I {...}
> > class Bar {...} // structurally compatible to I
> > 
> > template tp (I) {...}
> > 
> > 1) .Net nominative typing:
> > tp!(Foo) // OK
> > tp!(Bar) //not OK
> > 
> > 2) structural typing (similllar to Go?)
> > tp!(Foo) // OK
> > tp!(Bar) // also OK
> > 
> > 3) C++ style templates where the compatibility check is against the *body* 
> > of the template.
> > 
> > of the three above I think option 3 is the worst design and option 2 is my 
> > favorite design. I think that in reality you'll almost always want to 
> > define such an interface and I really can't think of any useful use cases 
> > for an unrestricted template parameter as in C++. 
> 
> You forgot option 4:
> 
> 4) D2 constrained templates, where the condition is checked inside the 
> template constraint.
> 
> This is more powerful than option 2, because:
> 
> (1) there are cases where you want MORE constraints than simply an 
> interface; and (2) only a subset of constraints can be expressed as an 
> interface.
> Also a minor point: (3) interfaces don't work for built-in types.
> 
> Better still would be to make it impossible to compile a template which 
> made use of a feature not provided through a constraint.
> 

I wouldn't give that a sepoarate option number, IMO this is a variation on 
option2. regarding your notes:
when you can express the same concept in both ways, using an interface is esier 
to read & understand IMO. What about having a combination of the two designs? 
you define an interface and allow optionally defining additional constraints 
_on_the_interface_ instead of the template.
I think this complies with your points (1) and (2) and is better since you 
don't need to repeat the constraints at the call site (each template that uses 
that type needs to repeat the constraint).
even if you factor out the checks into a separate "isFoo" template you still 
need to add to each template declaration "if isFoo!(T)" which really should be 
done by the compiler instead.

regarding point(3) - this is orthogonal IMO. Ideally I'd like to see this 
distinction between builtin type and user defined one removed. int should be 
treated in the same manner as a user defined struct. 

I completely agree about not compiling templates that use features not defined 
by constraints. This is in fact the main point I was trying to make in this 
thread. 

Reply via email to