Template constraints

w0rp via Digitalmars-d digitalmars-d at puremagic.com
Sun Mar 15 03:40:16 PDT 2015


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.


More information about the Digitalmars-d mailing list