www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bugs in template constraints

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
There seem to be some bugs with template constraints. Here's a reduce example
(from TDPL) which will not compile:

import std.stdio;
import std.range;

 property bool empty(T)(T[] a) { return a.length == 0; }
 property ref T front(T)(T[] a) { return a[0]; }
void popFront(T)(ref T[] a) { a = a[1 .. $]; }


V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof(x = fun(x, range.front)))
        && is(typeof(range.empty) == bool)
        && is(typeof(range.popFront())))
{
    //~ writeln(is(typeof(x = fun(x, range.front))));
    //~ writeln(is(typeof(range.empty) == bool));
    //~ writeln(is(typeof(range.popFront())));
    
    for ( ; !range.empty; range.popFront()) {
        x = fun(x, range.front);
    }
    return x;
}

unittest {
    int[] r = [10, 14, 3, 5, 23];
    
    // compute sum
    int sum = reduce!((a, b) { return a + b; })(0, r);
    assert(sum == 55);
    
    // compute minimum
    int min = reduce!((a, b) { return a < b ? a : b; })(r[0], r);
    assert(min == 3);
}

void main()
{
}

Errors:
reduce_original.d(28): Error: template reduce_original.reduce(alias fun,V,R) if
(is(typeof(x = fun(x,range.front))) && is(typeof(range.empty) == bool) &&
is(typeof(range.popFront()))) does not match any function template declaration
reduce_original.d(28): Error: template reduce_original.reduce(alias fun,V,R) if
(is(typeof(x = fun(x,range.front))) && is(typeof(range.empty) == bool) &&
is(typeof(range.popFront()))) cannot deduce template function from argument
types !(__dgliteral1)(int,int[])
reduce_original.d(28): Error: template instance errors instantiating template
reduce_original.d(32): Error: template reduce_original.reduce(alias fun,V,R) if
(is(typeof(x = fun(x,range.front))) && is(typeof(range.empty) == bool) &&
is(typeof(range.popFront()))) does not match any function template declaration
reduce_original.d(32): Error: template reduce_original.reduce(alias fun,V,R) if
(is(typeof(x = fun(x,range.front))) && is(typeof(range.empty) == bool) &&
is(typeof(range.popFront()))) cannot deduce template function from argument
types !(__dgliteral4)(int,int[])
reduce_original.d(32): Error: template instance errors instantiating template


If I comment out the constraints, and uncomment those writeln's - which are the
same as the constraints - like so:

V reduce(alias fun, V, R)(V x, R range)
    //~ if (is(typeof(x = fun(x, range.front)))
        //~ && is(typeof(range.empty) == bool)
        //~ && is(typeof(range.popFront())))
{
    writeln(is(typeof(x = fun(x, range.front))));
    writeln(is(typeof(range.empty) == bool));
    writeln(is(typeof(range.popFront())));
    
    for ( ; !range.empty; range.popFront()) {
        x = fun(x, range.front);
    }
    return x;
}

I will get all true results back:

true
true
true
true
true
true

I'm filing a bug unless something else is to blame here.
Aug 03 2010
next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--00032555834a1645bf048cf0688d
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 3, 2010 at 20:59, Andrej Mitrovic <andrej.mitrovich gmail.com>wrote:

 There seem to be some bugs with template constraints. Here's a reduce
 example (from TDPL) which will not compile:


 V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof(x = fun(x, range.front)))
        && is(typeof(range.empty) == bool)
        && is(typeof(range.popFront())))

 I'm filing a bug unless something else is to blame here.

I think that's because you cannot directly take the type of a statement. The assignment in the first typeof() is to blame. To make a statement into an expression, transform it into an anonymous void delegate(): put it in braces (with a semicolon at the end) and call it like a function, like this: V reduce(alias fun, V, R)(V x, R range) if (is({ typeof(x = fun(x, range.front);}())) && is(typeof(range.empty) == bool) && is(typeof(range.popFront()))) {...} Or, more readable, wrap all the code you want to test into curly brackets and evaluates its global return type: V reduce(alias fun, V, R)(V x, R range) if (is(typeof({ // I want to be able to do that with an R and a V: x = fun(x, range.front); if (range.empty) {}; range.popFront(); }()))) {...} It's a D idiom you'll see in many places in the standard library. I personally find it a _bit_ heavy on parenthesis, even though I like Lisp. Philippe --00032555834a1645bf048cf0688d Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 20:59, Andrej Mit= rovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com">a= ndrej.mitrovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma= il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef= t:1ex;"> There seem to be some bugs with template constraints. Here&#39;s a reduce e= xample (from TDPL) which will not compile:<br><br> <br> V reduce(alias fun, V, R)(V x, R range)<br> =A0 =A0if (is(typeof(x =3D fun(x, range.front)))<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.popFront())))<br></blockquote><d= iv>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo= rder-left:1px #ccc solid;padding-left:1ex;">I&#39;m filing a bug unless som= ething else is to blame here.<br> </blockquote></div><br><div>I think that&#39;s because you cannot directly = take the type of a statement. The assignment in the first typeof() is to bl= ame. To make a statement into an expression, transform it into an anonymous= void delegate(): put it in braces (with a semicolon at the end) and call i= t like a function, like this:</div> <div><br></div><div>V reduce(alias fun, V, R)(V x, R range)</div><div>=A0= =A0 =A0if (is({ typeof(x =3D fun(x, range.front);}()))</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.popFront())))</div> <div>{...}</div><div><br></div><div>Or, more readable, wrap all the code yo= u want to test into curly brackets and evaluates its global return type:</d= iv><div><br></div><div><div><br></div><div>V reduce(alias fun, V, R)(V x, R= range)</div> <div>=A0=A0 if (is(typeof({ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0// I want to be able to do that with an R and a V:</div><div>= =A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D fun(x, range.front);</div><div>=A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (range.empty) {};</div><div>=A0=A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 range.popFront();</div> <div>=A0=A0 }())))</div><div>=A0</div></div><div>{...}</div><div><br></div>= <div>It&#39;s a D idiom you&#39;ll see in many places in the standard libra= ry. I personally find it a _bit_ heavy on parenthesis, even though I like L= isp.</div> <div><br></div><div><br></div><div>Philippe</div> --00032555834a1645bf048cf0688d--
Aug 03 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
--0016364ef6faf62caa048cf0c7df
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 3, 2010 at 9:34 PM, Philippe Sigaud
<philippe.sigaud gmail.com>wrote:

 On Tue, Aug 3, 2010 at 20:59, Andrej Mitrovic
<andrej.mitrovich gmail.com>wrote:

 There seem to be some bugs with template constraints. Here's a reduce
 example (from TDPL) which will not compile:


 V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof(x = fun(x, range.front)))
        && is(typeof(range.empty) == bool)
        && is(typeof(range.popFront())))

 I'm filing a bug unless something else is to blame here.

I think that's because you cannot directly take the type of a statement. The assignment in the first typeof() is to blame. To make a statement into an expression, transform it into an anonymous void delegate(): put it in braces (with a semicolon at the end) and call it like a function, like this: V reduce(alias fun, V, R)(V x, R range) if (is({ typeof(x = fun(x, range.front);}())) && is(typeof(range.empty) == bool) && is(typeof(range.popFront()))) {...}

 Or, more readable, wrap all the code you want to test into curly brackets
 and evaluates its global return type:


 V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof({                              // I want to be able to do
 that with an R and a V:
                  x = fun(x, range.front);
                  if (range.empty) {};
                  range.popFront();
    }())))

 {...}

 It's a D idiom you'll see in many places in the standard library. I
 personally find it a _bit_ heavy on parenthesis, even though I like Lisp.


 Philippe

Yeah, those paranthesis are getting a bit scary now. :) I guess this one goes to the TDPL errata. Thanks for your help Philippe. --0016364ef6faf62caa048cf0c7df Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 9:34 PM, Philippe= Sigaud <span dir=3D"ltr">&lt;<a href=3D"mailto:philippe.sigaud gmail.com">= philippe.sigaud gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma= il_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(20= 4, 204, 204); padding-left: 1ex;"> <br><br><div class=3D"gmail_quote"><div class=3D"im">On Tue, Aug 3, 2010 at= 20:59, Andrej Mitrovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitr= ovich gmail.com" target=3D"_blank">andrej.mitrovich gmail.com</a>&gt;</span=
 wrote:<br>

border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class= =3D"im"> There seem to be some bugs with template constraints. Here&#39;s a reduce e= xample (from TDPL) which will not compile:<br><br> <br></div><div class=3D"im"> V reduce(alias fun, V, R)(V x, R range)<br> =A0 =A0if (is(typeof(x =3D fun(x, range.front)))<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.popFront())))<br></div></blockqu= ote><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0p= t 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"=
I&#39;m filing a bug unless something else is to blame here.<br>

</blockquote></div><br><div>I think that&#39;s because you cannot directly = take the type of a statement. The assignment in the first typeof() is to bl= ame. To make a statement into an expression, transform it into an anonymous= void delegate(): put it in braces (with a semicolon at the end) and call i= t like a function, like this:</div> <div class=3D"im"> <div><br></div><div>V reduce(alias fun, V, R)(V x, R range)</div><div>=A0= =A0 =A0if (is({ typeof(x =3D fun(x, range.front);}()))</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.popFront())))</div> </div><div>{...}</div><div><br></div></blockquote><div><br>The { comes afte= r &quot;typeof(&quot; as in your second example, and then it compiles.<br>= =A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8= ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> <div></div><div>Or, more readable, wrap all the code you want to test into = curly brackets and evaluates its global return type:</div><div><br></div><d= iv><div class=3D"im"><div><br></div><div>V reduce(alias fun, V, R)(V x, R r= ange)</div> </div><div>=A0=A0 if (is(typeof({ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0// I want to be able to do that with an R and a V:</div>= <div>=A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D fun(x, range.front);</div><di= v>=A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (range.empty) {};</div><div> =A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 range.popFront();</div> <div>=A0=A0 }())))</div><div>=A0</div></div><div>{...}</div><div><br></div>= <div>It&#39;s a D idiom you&#39;ll see in many places in the standard libra= ry. I personally find it a _bit_ heavy on parenthesis, even though I like L= isp.</div> <div><br></div><font color=3D"#888888"><div><br></div><div>Philippe</div> </font></blockquote></div><br>Yeah, those paranthesis are getting a bit sca= ry now. :) I guess this one goes to the TDPL errata.<br><br>Thanks for your= help Philippe.<br><br><br> --0016364ef6faf62caa048cf0c7df--
Aug 03 2010
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
--0016368330526f4264048cf0d2bc
Content-Type: text/plain; charset=ISO-8859-1

Oh and there's a shorter way to write this example, by using isInputRange
from std.range, like so:

if (isInputRange!R && is(typeof({x = fun(x, range.front);})))

This was in TDPL (except the {}'s which are missing).

On Tue, Aug 3, 2010 at 10:01 PM, Andrej Mitrovic <andrej.mitrovich gmail.com
 wrote:

 On Tue, Aug 3, 2010 at 9:34 PM, Philippe Sigaud <philippe.sigaud gmail.com
 wrote:

 On Tue, Aug 3, 2010 at 20:59, Andrej Mitrovic <andrej.mitrovich gmail.com
 wrote:

 There seem to be some bugs with template constraints. Here's a reduce
 example (from TDPL) which will not compile:


 V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof(x = fun(x, range.front)))
        && is(typeof(range.empty) == bool)
        && is(typeof(range.popFront())))

 I'm filing a bug unless something else is to blame here.

I think that's because you cannot directly take the type of a statement. The assignment in the first typeof() is to blame. To make a statement into an expression, transform it into an anonymous void delegate(): put it in braces (with a semicolon at the end) and call it like a function, like this: V reduce(alias fun, V, R)(V x, R range) if (is({ typeof(x = fun(x, range.front);}())) && is(typeof(range.empty) == bool) && is(typeof(range.popFront()))) {...}

compiles.
 Or, more readable, wrap all the code you want to test into curly brackets
 and evaluates its global return type:


 V reduce(alias fun, V, R)(V x, R range)
    if (is(typeof({                              // I want to be able to do
 that with an R and a V:
                  x = fun(x, range.front);
                  if (range.empty) {};
                  range.popFront();
    }())))

 {...}

 It's a D idiom you'll see in many places in the standard library. I
 personally find it a _bit_ heavy on parenthesis, even though I like Lisp.


 Philippe

Yeah, those paranthesis are getting a bit scary now. :) I guess this one goes to the TDPL errata. Thanks for your help Philippe.

--0016368330526f4264048cf0d2bc Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Oh and there&#39;s a shorter way to write this example, by using isInputRan= ge from std.range, like so:<br><br>if (isInputRange!R &amp;&amp; is(typeof(= {x =3D fun(x, range.front);})))<br><br>This was in TDPL (except the {}&#39;= s which are missing).<br> <br><div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 10:01 PM, Andrej Mitr= ovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com">an= drej.mitrovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmai= l_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204= , 204, 204); padding-left: 1ex;"> <br><br><div class=3D"gmail_quote"><div class=3D"im">On Tue, Aug 3, 2010 at= 9:34 PM, Philippe Sigaud <span dir=3D"ltr">&lt;<a href=3D"mailto:philippe.= sigaud gmail.com" target=3D"_blank">philippe.sigaud gmail.com</a>&gt;</span=
 wrote:<br>

r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> <br><br><div class=3D"gmail_quote"><div>On Tue, Aug 3, 2010 at 20:59, Andre= j Mitrovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.c= om" target=3D"_blank">andrej.mitrovich gmail.com</a>&gt;</span> wrote:<br> </div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex;= border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div> There seem to be some bugs with template constraints. Here&#39;s a reduce e= xample (from TDPL) which will not compile:<br><br> <br></div><div> V reduce(alias fun, V, R)(V x, R range)<br> =A0 =A0if (is(typeof(x =3D fun(x, range.front)))<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)<br> =A0 =A0 =A0 =A0&amp;&amp; is(typeof(range.popFront())))<br></div></blockqu= ote><div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0p= t 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"=
I&#39;m filing a bug unless something else is to blame here.<br>

</blockquote></div><br><div>I think that&#39;s because you cannot directly = take the type of a statement. The assignment in the first typeof() is to bl= ame. To make a statement into an expression, transform it into an anonymous= void delegate(): put it in braces (with a semicolon at the end) and call i= t like a function, like this:</div> <div> <div><br></div><div>V reduce(alias fun, V, R)(V x, R range)</div><div>=A0= =A0 =A0if (is({ typeof(x =3D fun(x, range.front);}()))</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0= =A0 =A0&amp;&amp; is(typeof(range.popFront())))</div> </div><div>{...}</div><div><br></div></blockquote></div><div><br>The { come= s after &quot;typeof(&quot; as in your second example, and then it compiles= .<br>=A0</div><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"= margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); paddi= ng-left: 1ex;"> <div></div><div>Or, more readable, wrap all the code you want to test into = curly brackets and evaluates its global return type:</div><div><br></div><d= iv><div><div><br></div><div>V reduce(alias fun, V, R)(V x, R range)</div> </div><div>=A0=A0 if (is(typeof({ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0// I want to be able to do that with an R and a V:</div>= <div>=A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 x =3D fun(x, range.front);</div><di= v>=A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (range.empty) {};</div><div> =A0=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 range.popFront();</div> <div>=A0=A0 }())))</div><div>=A0</div></div><div>{...}</div><div><br></div>= <div>It&#39;s a D idiom you&#39;ll see in many places in the standard libra= ry. I personally find it a _bit_ heavy on parenthesis, even though I like L= isp.</div> <div><br></div><font color=3D"#888888"><div><br></div><div>Philippe</div> </font></blockquote></div></div><br>Yeah, those paranthesis are getting a b= it scary now. :) I guess this one goes to the TDPL errata.<br><br>Thanks fo= r your help Philippe.<br><br><br> </blockquote></div><br> --0016368330526f4264048cf0d2bc--
Aug 03 2010
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--00151747c070b37826048cf11611
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic <andrej.mitrovich gmail.com>wrote:

 Oh and there's a shorter way to write this example, by using isInputRange
 from std.range, like so:

 if (isInputRange!R && is(typeof({x = fun(x, range.front);})))

Does this work, without the () after the } ?
 This was in TDPL (except the {}'s which are missing).

As I said, abstracting away common constraints is a common trick. Have a look at std.range, you'll see a bunch of these. Philippe --00151747c070b37826048cf11611 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 22:04, Andrej Mit= rovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com">a= ndrej.mitrovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gma= il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef= t:1ex;"> Oh and there&#39;s a shorter way to write this example, by using isInputRan= ge from std.range, like so:<br><br>if (isInputRange!R &amp;&amp; is(typeof(= {x =3D fun(x, range.front);})))<br></blockquote><div><br></div><div>Does th= is work, without the () after the } ?</div> <div>=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;= border-left:1px #ccc solid;padding-left:1ex;">This was in TDPL (except the = {}&#39;s which are missing).</blockquote><div><br></div><div>As I said, abs= tracting away common constraints is a common trick. Have a look at std.rang= e, you&#39;ll see a bunch of these.</div> <div><br></div><div><br></div><div>Philippe=A0</div></div> --00151747c070b37826048cf11611--
Aug 03 2010
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
--0016e649d5dc0222a4048cf1b4d0
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 3, 2010 at 10:23 PM, Philippe Sigaud
<philippe.sigaud gmail.com>wrote:

 On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic
<andrej.mitrovich gmail.com>wrote:

 Oh and there's a shorter way to write this example, by using isInputRange
 from std.range, like so:

 if (isInputRange!R && is(typeof({x = fun(x, range.front);})))

Does this work, without the () after the } ?

I haven't even noticed those. In the following, If I add the pair of ()'s I get void as a return type. If I remove them, I get void delegate(): writeln(typeid(typeof( delegate void () {int x = 1;}()))); // writes void writeln(typeid(typeof( delegate void () {int x = 1;}))); // writes void delegate() So I definitely need to add them. When not added the expression evaluates to void delegate(), which is a valid type and the constraint then passes. If I understood everything, this code in the constraint: is(typeof({x = fun(x, range.front);}() ))) creates an anonymous function, the compiler sees it's trying to access x so it makes it a delegate, and it infers that the function takes no arguments and the return type is void. Did I get this right? This was in TDPL (except the {}'s which are missing).
 As I said, abstracting away common constraints is a common trick. Have a
 look at std.range, you'll see a bunch of these.


 Philippe

--0016e649d5dc0222a4048cf1b4d0 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><br><div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 10:23 PM, Philipp= e Sigaud <span dir=3D"ltr">&lt;<a href=3D"mailto:philippe.sigaud gmail.com"=
philippe.sigaud gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gm=

04, 204, 204); padding-left: 1ex;"> <br><br><div class=3D"gmail_quote"><div class=3D"im">On Tue, Aug 3, 2010 at= 22:04, Andrej Mitrovic <span dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitr= ovich gmail.com" target=3D"_blank">andrej.mitrovich gmail.com</a>&gt;</span=
 wrote:<br>

r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> Oh and there&#39;s a shorter way to write this example, by using isInputRan= ge from std.range, like so:<br><br>if (isInputRange!R &amp;&amp; is(typeof(= {x =3D fun(x, range.front);})))<br></blockquote><div><br></div></div><div> Does this work, without the () after the } ?</div><div class=3D"im"> <div>=A0</div></div></div></blockquote><div><br>I haven&#39;t even noticed = those. <br><br>In the following, If I add the pair of ()&#39;s I get void a= s a return type. If I remove them, I get void delegate():<br><br>writeln(ty= peid(typeof( delegate void () {int x =3D 1;}())));=A0=A0=A0 // writes void<= br> writeln(typeid(typeof( delegate void () {int x =3D 1;})));=A0=A0=A0=A0=A0 /= / writes void delegate()<br>=A0<br>So I definitely need to add them. When n= ot added the expression evaluates to void delegate(), which is a valid type= and the constraint then passes.<br> <br>If I understood everything, this code in the constraint:<br><br>is(type= of({x =3D fun(x, range.front);}() )))<br><br>creates an anonymous function,= the compiler sees it&#39;s trying to access x so it makes it a delegate, a= nd it infers that the function takes no arguments and the return type is vo= id. Did I get this right?<br> <br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0p= t 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><di= v class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gmail_quote"= style=3D"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 2= 04); padding-left: 1ex;"> This was in TDPL (except the {}&#39;s which are missing).</blockquote><div>= <br></div></div><div>As I said, abstracting away common constraints is a co= mmon trick. Have a look at std.range, you&#39;ll see a bunch of these.</div=

<div><br></div><font color=3D"#888888"><div><br></div><div>Philippe=A0</div=
</font></div>

--0016e649d5dc0222a4048cf1b4d0--
Aug 03 2010
parent Pelle <pelle.mansson gmail.com> writes:
On 08/03/2010 11:07 PM, Andrej Mitrovic wrote:
 On Tue, Aug 3, 2010 at 10:23 PM, Philippe Sigaud
 <philippe.sigaud gmail.com <mailto:philippe.sigaud gmail.com>> wrote:



     On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic
     <andrej.mitrovich gmail.com <mailto:andrej.mitrovich gmail.com>> wrote:

         Oh and there's a shorter way to write this example, by using
         isInputRange from std.range, like so:

         if (isInputRange!R && is(typeof({x = fun(x, range.front);})))


     Does this work, without the () after the } ?


 I haven't even noticed those.

 In the following, If I add the pair of ()'s I get void as a return type.
 If I remove them, I get void delegate():

 writeln(typeid(typeof( delegate void () {int x = 1;}())));    // writes void
 writeln(typeid(typeof( delegate void () {int x = 1;})));      // writes
 void delegate()

 So I definitely need to add them. When not added the expression
 evaluates to void delegate(), which is a valid type and the constraint
 then passes.

 If I understood everything, this code in the constraint:

 is(typeof({x = fun(x, range.front);}() )))

 creates an anonymous function, the compiler sees it's trying to access x
 so it makes it a delegate, and it infers that the function takes no
 arguments and the return type is void. Did I get this right?

You only need to call it if you want to check the return type. You cannot create a function with content that can't compile, so in this case, the () isn't needed. Correct me if I'm wrong, of course. :)
Aug 03 2010
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
--0015174c4298e29ef5048cf1fc8a
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 3, 2010 at 23:07, Andrej Mitrovic <andrej.mitrovich gmail.com>wrote:

 If I understood everything, this code in the constraint:

 is(typeof({x = fun(x, range.front);}() )))

 creates an anonymous function, the compiler sees it's trying to access x so
 it makes it a delegate, and it infers that the function takes no arguments
 and the return type is void. Did I get this right?

Yes, that's it. If the enclosed statements are OK, then the whole delegate compiles, gets a type (void delegate() ), and so on, though is(typeof()). So, using it as a way to get template constraints to work on many statements was not planned that way, I think. But it works :) Basically any D block statement: { statements;} can be seen as a void delegate(). see http://www.digitalmars.com/d/2.0/lazy-evaluation.html and http://www.digitalmars.com/d/2.0/statement.html#ScopeStatement for an example of this. Philippe --0015174c4298e29ef5048cf1fc8a Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On Tue, Aug 3, 2010 at 23:07, Andrej Mitrovic <s= pan dir=3D"ltr">&lt;<a href=3D"mailto:andrej.mitrovich gmail.com">andrej.mi= trovich gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote= " style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"> <div class=3D"gmail_quote"><div><br>If I understood everything, this code i= n the constraint:<br><br>is(typeof({x =3D fun(x, range.front);}() )))<br><b= r>creates an anonymous function, the compiler sees it&#39;s trying to acces= s x so it makes it a delegate, and it infers that the function takes no arg= uments and the return type is void. Did I get this right?<br> </div></div></blockquote><div><br></div><div>Yes, that&#39;s it. If the enc= losed statements are OK, then the whole delegate compiles, gets a type (voi= d delegate() ), and so on, though is(typeof()).</div><div><br></div><div> So, using it as a way to get template constraints to work on many statement= s was not planned that way, I think. But it works :)</div><div><br></div><d= iv>Basically any D block statement: { statements;} can be seen as a void de= legate().=A0</div> <div><br></div><div>see=A0<a href=3D"http://www.digitalmars.com/d/2.0/lazy-= evaluation.html">http://www.digitalmars.com/d/2.0/lazy-evaluation.html</a><= /div><div>and=A0<a href=3D"http://www.digitalmars.com/d/2.0/statement.html#= ScopeStatement">http://www.digitalmars.com/d/2.0/statement.html#ScopeStatem= ent</a>=A0for an example of this.</div> <div><br></div><div>Philippe</div><div><br></div></div> --0015174c4298e29ef5048cf1fc8a--
Aug 03 2010
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
--0016367fbad467f19a048cf28f18
Content-Type: text/plain; charset=ISO-8859-1

I guess that would make sense. With {}() I could add a comparison for the
return type if I ever needed that.

I did take a look in std.range, and pretty much all the templates there use
the {}() syntax.

On Tue, Aug 3, 2010 at 11:53 PM, Pelle <pelle.mansson gmail.com> wrote:

 On 08/03/2010 11:07 PM, Andrej Mitrovic wrote:

 On Tue, Aug 3, 2010 at 10:23 PM, Philippe Sigaud
 <philippe.sigaud gmail.com <mailto:philippe.sigaud gmail.com>> wrote:



    On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic
    <andrej.mitrovich gmail.com <mailto:andrej.mitrovich gmail.com>>
 wrote:

        Oh and there's a shorter way to write this example, by using
        isInputRange from std.range, like so:

        if (isInputRange!R && is(typeof({x = fun(x, range.front);})))


    Does this work, without the () after the } ?


 I haven't even noticed those.

 In the following, If I add the pair of ()'s I get void as a return type.
 If I remove them, I get void delegate():

 writeln(typeid(typeof( delegate void () {int x = 1;}())));    // writes
 void
 writeln(typeid(typeof( delegate void () {int x = 1;})));      // writes
 void delegate()

 So I definitely need to add them. When not added the expression
 evaluates to void delegate(), which is a valid type and the constraint
 then passes.

 If I understood everything, this code in the constraint:

 is(typeof({x = fun(x, range.front);}() )))

 creates an anonymous function, the compiler sees it's trying to access x
 so it makes it a delegate, and it infers that the function takes no
 arguments and the return type is void. Did I get this right?

create a function with content that can't compile, so in this case, the () isn't needed. Correct me if I'm wrong, of course. :)

--0016367fbad467f19a048cf28f18 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I guess that would make sense. With {}() I could add a comparison for the r= eturn type if I ever needed that.<br><br>I did take a look in std.range, an= d pretty much all the templates there use the {}() syntax.<br><br><div clas= s=3D"gmail_quote"> On Tue, Aug 3, 2010 at 11:53 PM, Pelle <span dir=3D"ltr">&lt;<a href=3D"mai= lto:pelle.mansson gmail.com">pelle.mansson gmail.com</a>&gt;</span> wrote:<= br><blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; bo= rder-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> On 08/03/2010 11:07 PM, Andrej Mitrovic wrote:<br> <blockquote class=3D"gmail_quote" style=3D"margin: 0pt 0pt 0pt 0.8ex; borde= r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div class=3D"im"=

<br> On Tue, Aug 3, 2010 at 10:23 PM, Philippe Sigaud<br> &lt;<a href=3D"mailto:philippe.sigaud gmail.com" target=3D"_blank">philippe= .sigaud gmail.com</a> &lt;mailto:<a href=3D"mailto:philippe.sigaud gmail.co= m" target=3D"_blank">philippe.sigaud gmail.com</a>&gt;&gt; wrote:<br> <br> <br> <br> =A0 =A0On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic<br></div><div class= =3D"im"> =A0 =A0&lt;<a href=3D"mailto:andrej.mitrovich gmail.com" target=3D"_blank"=
andrej.mitrovich gmail.com</a> &lt;mailto:<a href=3D"mailto:andrej.mitrovi=

e:<br> <br> =A0 =A0 =A0 =A0Oh and there&#39;s a shorter way to write this example, by = using<br> =A0 =A0 =A0 =A0isInputRange from std.range, like so:<br> <br> =A0 =A0 =A0 =A0if (isInputRange!R &amp;&amp; is(typeof({x =3D fun(x, range= .front);})))<br> <br> <br> =A0 =A0Does this work, without the () after the } ?<br> <br> <br></div><div class=3D"im"> I haven&#39;t even noticed those.<br> <br> In the following, If I add the pair of ()&#39;s I get void as a return type= .<br> If I remove them, I get void delegate():<br> <br> writeln(typeid(typeof( delegate void () {int x =3D 1;}()))); =A0 =A0// writ= es void<br> writeln(typeid(typeof( delegate void () {int x =3D 1;}))); =A0 =A0 =A0// wr= ites<br> void delegate()<br> <br> So I definitely need to add them. When not added the expression<br> evaluates to void delegate(), which is a valid type and the constraint<br> then passes.<br> <br></div><div class=3D"im"> If I understood everything, this code in the constraint:<br> <br> is(typeof({x =3D fun(x, range.front);}() )))<br> <br> creates an anonymous function, the compiler sees it&#39;s trying to access = x<br> so it makes it a delegate, and it infers that the function takes no<br> arguments and the return type is void. Did I get this right?<br> <br> </div></blockquote> <br> You only need to call it if you want to check the return type. You cannot c= reate a function with content that can&#39;t compile, so in this case, the = () isn&#39;t needed.<br> <br> Correct me if I&#39;m wrong, of course. :)<br> </blockquote></div><br> --0016367fbad467f19a048cf28f18--
Aug 03 2010