digitalmars.D - Bugs in template constraints
- Andrej Mitrovic <andrej.mitrovich gmail.com> Aug 03 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Aug 03 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Aug 03 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Aug 03 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Aug 03 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Aug 03 2010
- Pelle <pelle.mansson gmail.com> Aug 03 2010
- Philippe Sigaud <philippe.sigaud gmail.com> Aug 03 2010
- Andrej Mitrovic <andrej.mitrovich gmail.com> Aug 03 2010
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
--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"><<a href=3D"mailto:andrej.mitrovich gmail.com">a= ndrej.mitrovich gmail.com</a>></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'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&& is(typeof(range.empty) =3D=3D bool)<br> =A0 =A0 =A0 =A0&& 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'm filing a bug unless som= ething else is to blame here.<br> </blockquote></div><br><div>I think that'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&& is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0= =A0 =A0&& 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's a D idiom you'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
--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"><<a href=3D"mailto:philippe.sigaud gmail.com">= philippe.sigaud gmail.com</a>></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"><<a href=3D"mailto:andrej.mitr= ovich gmail.com" target=3D"_blank">andrej.mitrovich gmail.com</a>></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'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&& is(typeof(range.empty) =3D=3D bool)<br> =A0 =A0 =A0 =A0&& 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'm filing a bug unless something else is to blame here.<br>
</blockquote></div><br><div>I think that'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&& is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0= =A0 =A0&& is(typeof(range.popFront())))</div> </div><div>{...}</div><div><br></div></blockquote><div><br>The { comes afte= r "typeof(" 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's a D idiom you'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
--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's a shorter way to write this example, by using isInputRan=
ge from std.range, like so:<br><br>if (isInputRange!R && is(typeof(=
{x =3D fun(x, range.front);})))<br><br>This was in TDPL (except the {}'=
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"><<a href=3D"mailto:andrej.mitrovich gmail.com">an=
drej.mitrovich gmail.com</a>></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"><<a href=3D"mailto:philippe.=
sigaud gmail.com" target=3D"_blank">philippe.sigaud gmail.com</a>></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"><<a href=3D"mailto:andrej.mitrovich gmail.c=
om" target=3D"_blank">andrej.mitrovich gmail.com</a>></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'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&& is(typeof(range.empty) =3D=3D bool)<br>
=A0 =A0 =A0 =A0&& 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'm filing a bug unless something else is to blame here.<br>
</blockquote></div><br><div>I think that'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&& is(typeof(range.empty) =3D=3D bool)</div><div>=A0=A0 =A0=
=A0 =A0&& is(typeof(range.popFront())))</div>
</div><div>{...}</div><div><br></div></blockquote></div><div><br>The { come=
s after "typeof(" 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's a D idiom you'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
--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"><<a href=3D"mailto:andrej.mitrovich gmail.com">a= ndrej.mitrovich gmail.com</a>></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's a shorter way to write this example, by using isInputRan= ge from std.range, like so:<br><br>if (isInputRange!R && 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 = {}'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'll see a bunch of these.</div> <div><br></div><div><br></div><div>Philippe=A0</div></div> --00151747c070b37826048cf11611--
Aug 03 2010
--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"><<a href=3D"mailto:philippe.sigaud gmail.com"=philippe.sigaud gmail.com</a>></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"><<a href=3D"mailto:andrej.mitr= ovich gmail.com" target=3D"_blank">andrej.mitrovich gmail.com</a>></span=wrote:<br>
r-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"> Oh and there's a shorter way to write this example, by using isInputRan= ge from std.range, like so:<br><br>if (isInputRange!R && 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't even noticed = those. <br><br>In the following, If I add the pair of ()'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'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 {}'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'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
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
--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"><<a href=3D"mailto:andrej.mitrovich gmail.com">andrej.mi= trovich gmail.com</a>></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'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'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
--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"><<a href=3D"mai=
lto:pelle.mansson gmail.com">pelle.mansson gmail.com</a>></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>
<<a href=3D"mailto:philippe.sigaud gmail.com" target=3D"_blank">philippe=
.sigaud gmail.com</a> <mailto:<a href=3D"mailto:philippe.sigaud gmail.co=
m" target=3D"_blank">philippe.sigaud gmail.com</a>>> wrote:<br>
<br>
<br>
<br>
=A0 =A0On Tue, Aug 3, 2010 at 22:04, Andrej Mitrovic<br></div><div class=
=3D"im">
=A0 =A0<<a href=3D"mailto:andrej.mitrovich gmail.com" target=3D"_blank"=
andrej.mitrovich gmail.com</a> <mailto:<a href=3D"mailto:andrej.mitrovi=
e:<br>
<br>
=A0 =A0 =A0 =A0Oh and there'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 && 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't even noticed those.<br>
<br>
In the following, If I add the pair of ()'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'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't compile, so in this case, the =
() isn't needed.<br>
<br>
Correct me if I'm wrong, of course. :)<br>
</blockquote></div><br>
--0016367fbad467f19a048cf28f18--
Aug 03 2010









Philippe Sigaud <philippe.sigaud gmail.com> 