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