D's greatest mistakes

Andrej Mitrovic andrej.mitrovich at gmail.com
Mon Nov 29 16:47:01 PST 2010


On 11/29/10, Simen kjaeraas <simen.kjaras at gmail.com> wrote:
> Andrej Mitrovic <andrej.mitrovich at gmail.com> wrote:
>
>> Why not do the same for templates? Something like this:
>>
>> void foo(A, B, C)(A a, B b, C c)
>> constraint
>> {
>>     isDynamicArray(a);
>>     isIterable(a);
>>
>> }
>
> Consider:
>
> void foo( A )( A a )
> constraint {
>    isBar!A;
> }
>
>
> void foo( B )( B a )
> constraint {
>    isQux!B;
> }
>
> Which error message should I show?
>
> --
> Simen
>

I'm not sure what you're getting at. :)

What I meant was something like the following example:

import std.stdio;
import std.range;

void myreverse(Range)(Range r)
if (isBidirectionalRange!(Range)
        && hasSwappableElements!(Range)
        && is(Range == int[]))
{
}
void main()
{
        uint[] x = [4, 5, 6];
        myreverse(x);
}

Here you get 2 very long error messages which don't help you much at all:
constraints.d(14): Error: template constraints.myreverse(Range) if (isBidirectio
nalRange!(Range) && hasSwappableElements!(Range) && is(Range == int[])) does not
 match any function template declaration
constraints.d(14): Error: template constraints.myreverse(Range) if (isBidirectio
nalRange!(Range) && hasSwappableElements!(Range) && is(Range == int[])) cannot d
educe template function from argument types !()(uint[])

The compiler never tells you which of the calls in the constraint
returned false, whether it was isBidirectionalRange,
hasSwappableElements, or the last "is(Range == int[])", since it's all
wrapped in a big if block and the compiler only cares if the block
evaluates to true or false.

What I would prefer is if we had code similar to this:

import std.stdio;
import std.range;

void myreverse(Range)(Range r)
constraints
{
        isBidirectionalRange!(Range);
        hasSwappableElements!(Range);
        is(Range == int[]);
}
body
{
}

void main()
{
        uint[] x = [4, 5, 6];
        myreverse(x);
}

And the compiler would check to see that all the statements
(expressions?) in the constraint block evaluate to true, otherwise it
would show a more informative error message, e.g.:

constraints.d(14): Error: template myreverse(Range) failed to
instantiate due to the following failed constraints:
  (45)    is(Range == int[]);
using argument types !()(uint[])

So a line number and the failed code in the constraint. If there are
multiple failed statements then it would list them all.

Of course this would mean that a constraint block is a special place,
but templates are special enough to have this constraint block, imo.
Error messages are the primary reason why I'd want constraint blocks,
because otherwise template errors can be quite uninformative.

But anyway it's just an idea and I'm probably missing something
important, I haven't used D in a while..


More information about the Digitalmars-d mailing list