www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - static foreach, expression-Based Contract Syntax and better error

reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
so the following
void foo(As...)(As as)
in
{
    static foreach (a ;as)
    assert(a>0);
}
do
{
}

void main()
{
      foo(1,2,3,4,5);
}

passes and compiles, whereas

void foo(As...)(As as)
static foreach (a ;as)
     in(a>0)
{
}

void main()
{
      foo(1,2,3,4,5);
}

does not compile.  I suppose thats fair enough, there is after 
all a not very verbose workaround.

I only note this because in researching examples for my multiple 
template constraints DIP[1], I noticed while I can make 
individual clauses easier to understand, I realised that 
recursive templates clauses are still going to be horrible so it 
would be useful to be able to do

void foo(As...)(As as)
static foreach (alias A ;As)
     if(isFoo!A)
{
     //...
}

and this was the closest thing syntactically. (yes I know I could 
have use allSatisfy here but for thing like un-recursing
ptrdiff_t countUntil(alias pred = "a == b", R, Rs...)(R haystack, 
Rs needles)
     if (isForwardRange!R
         && Rs.length > 0
         && isForwardRange!(Rs[0]) == isInputRange!(Rs[0])
         && is(typeof(startsWith!pred(haystack, needles[0])))
         && (Rs.length == 1
             || is(typeof(countUntil!pred(haystack, needles[1 .. 
$])))))
its not so simple)

Should this work? And is this something people would like to see 
added to the DIP?

[1]:https://github.com/thewilsonator/DIPs/blob/template-constraints/DIPs/DIP1xxx.md
Aug 07 2018
parent reply Basile B. <b2.temp gmx.com> writes:
On Tuesday, 7 August 2018 at 07:33:49 UTC, Nicholas Wilson wrote:
 so the following
 void foo(As...)(As as)
 in
 {
    static foreach (a ;as)
    assert(a>0);
 }
 do
 {
 }

 void main()
 {
      foo(1,2,3,4,5);
 }

 passes and compiles, whereas

 void foo(As...)(As as)
 static foreach (a ;as)
     in(a>0)
 {
 }

 void main()
 {
      foo(1,2,3,4,5);
 }

 does not compile.  I suppose thats fair enough, there is after 
 all a not very verbose workaround.

 I only note this because in researching examples for my 
 multiple template constraints DIP[1], I noticed while I can 
 make individual clauses easier to understand, I realised that 
 recursive templates clauses are still going to be horrible so 
 it would be useful to be able to do

 void foo(As...)(As as)
 static foreach (alias A ;As)
     if(isFoo!A)
 {
     //...
 }
 [...]
 Should this work? And is this something people would like to 
 see added to the DIP?
No. At this point syntax of contracts or constraints is getting *really* mad. I think it's better to put the static loop in the function body, especially since with assert you can format a nice message, while not with constraints.
Aug 07 2018
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Tuesday, 7 August 2018 at 08:20:55 UTC, Basile B. wrote:
 On Tuesday, 7 August 2018 at 07:33:49 UTC, Nicholas Wilson 
 wrote:
 so the following
 void foo(As...)(As as)
 in
 {
    static foreach (a ;as)
    assert(a>0);
 }
 do
 {
 }

 void main()
 {
      foo(1,2,3,4,5);
 }

 passes and compiles, whereas

 void foo(As...)(As as)
 static foreach (a ;as)
     in(a>0)
 {
 }

 void main()
 {
      foo(1,2,3,4,5);
 }

 does not compile.  I suppose thats fair enough, there is after 
 all a not very verbose workaround.

 I only note this because in researching examples for my 
 multiple template constraints DIP[1], I noticed while I can 
 make individual clauses easier to understand, I realised that 
 recursive templates clauses are still going to be horrible so 
 it would be useful to be able to do

 void foo(As...)(As as)
 static foreach (alias A ;As)
     if(isFoo!A)
 {
     //...
 }
 [...]
 Should this work? And is this something people would like to 
 see added to the DIP?
No. At this point syntax of contracts or constraints is getting *really* mad. I think it's better to put the static loop in the function body, especially since with assert you can format a nice message, while not with constraints.
I have decided to make the DIP be consistent with `in` contracts: that is allow both an expression form and block statement form. The block state meant can use static foreach to static assert on variadic lists, while the expression from is more concise.
Aug 16 2018