Template constraints

matovitch via Digitalmars-d digitalmars-d at puremagic.com
Sun Mar 15 06:46:06 PDT 2015

On Sunday, 15 March 2015 at 10:40:17 UTC, w0rp wrote:
> On Sunday, 15 March 2015 at 08:29:01 UTC, bearophile wrote:
>> Observe:
>> https://github.com/D-Programming-Language/phobos/pull/3054
>> Is this change the partial proof of another failure of a part 
>> of D language design? What's the point of template 
>> constraints? Aren't C++ Concepts better? Or to rephrase that 
>> in a less trollish way, can D be enhanced to add user-defined 
>> error messages to template constraints, and is such 
>> enhancement a good idea?
>> Bye,
>> bearophile
> It's funny you mentioned concepts, because I was just watching 
> Bjarne's CppCon 2014 keynote again and I took away two things 
> from it.
> 1. For the overwhelming majority of things Bjarne wants from 
> C++ mentioned in that keynote, D has done all of them, and 
> better...
> 2. ...except for concepts.
> I believe D does the template error message thing a *whole lot* 
> better than C++. That's all because of template constraints, 
> static if, and static assert, and I believe those are down to 
> Andrei's influence. (Though others likely deserve credit for 
> their design, implementation, and maintenance. As always you'll 
> probably have to nod to Kenji who works like crazy.)
> I've been wondering what we can do to make specifying 
> constraints for something like ranges a little easier to write, 
> with obviously some underlying complexities which will be hard 
> to implement. This doesn't address your concern about error 
> messages for constraints really, but what I've thought of is 
> roughly this.
> Say you write 'copy' currently. You'll do something like this.
> void copy(InputRange, OutputRange)(InputRange inputRange, 
> OutputRange)
> if (isInputRange!InputRange && isOutputRange!OutputRange) {
>     /* Some implementation of copying. */
> }
> Maybe you'll use less verbose names and all kinds of things, 
> but essentially that is what you're after. I've been wondering 
> if it's possible to use compiler magic to make this possible.
> // These names conflict with our interfaces in std.range, 
> whatever, imagine
> // some other name place of them if you like.
> template InputRange(T) {
>     enum InputRange = isInputRange!T;
> }
> // The newer syntax makes the above easier...
> enum OutputRange(T) = isOutputRange!T;
> // Now this works with magic...
> void copy()(InputRange inputRange, OutputRange outputRange) {
>     /* Some implementation of copying. */
> }
> If you write this now, the compiler will print an error saying, 
> "Hey, you just attempted to use this template which takes one 
> argument as a type in this paramter list right here." My idea 
> is to take that information and instead of returning an error, 
> just go, "Oh, I'll just add another template parameter onto the 
> end of your template parameter list here, replace the thing 
> which really should be a type here with T from the parameter 
> list, use deduction to insert the type for T and then use it, 
> then use the template you had originally as a test on the type 
> T yielding our boolean expression." I left the extra parens in 
> there for 'copy' as I reckon they'll probably be a requirement 
> anyway, and then you can't make accidental templates.
> You might have to read what I wrote four times to make sense of 
> it, but that's my crazy idea others can destroy. I'm more of a 
> wild idea guy than a formal specification guy.

I am not sure of what you want to do but that looks like 
"meta-type" like :

void copy(InputRange IRage, OutputRange ORange) (IRange src, 
Orange dest)  {
      /* Some implementation of copying. */

Hashkell has something like that for a long times (early 90s I 
think) wich is call type classes. Essentially, it checks that the 
type implement a certain interface (operators included). You 
could do the same in c++ with boost (now maybe std)::is_base_of I 

More information about the Digitalmars-d mailing list