Sorry I was on the plane and in a hurry so I posted to general reddit,
not programming. I now deleted that (sorry BCS) and now reposted under
programming. Vote me up please :o).
http://www.reddit.com/r/programming/comments/ceo9s/tech_talk_tips/
The point of the experiment was that Walter had hypothesized it's
possible his name is on a scrutiny/spam list. I removed his name from
the article and the results are mixed: when I posted in the general
reddit community the article didn't make it on the new articles list,
however this latest post in /programming/ was listed instantly. In the
meantime I saw that Walter's constrained templates article appeared but
with a delay. Go figure.
Andrei

Nice article, but when I read:
T gcd(T)(T a, T b)
if (is(typeof(a % b)))
{
...
}
Under the presence of such beauty as template constraint syntax is,
"is(typeof(a % b))" makes my eyes hurt, and my brain wonder. When you
get used to this idiom, it might not look to bad, but I'm seeing people
new to D wonder "why in the hell was that syntax used?" while they try
to decode what is(typeof()) means.
I think is really a shame, all the beauty and clarity gained by the
simple "if" of template constraints, is lost with the cryptic
is(typeof()) (well, maybe not all, but a significant part).
I would love to see this fixed/simplified. For example, by applying the
changes in suggested in bug 3702 [1]. This looks much better, and is
pretty clear to anyone (even people that doesn't know D):
T gcd(T)(T a, T b)
if (meta.compiles(a % b))
{
...
}
I guess at this point this is not going to happen for D2, a real shame
:S
The, the article made me think that, even when template constraints are
useful not only for improving error reporting, they are often used only
for that. Since the compiler knows all the operations a template
parameter will need to satisfy from the function body, it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler can
figure out). This way, the errors can be improved without user
intervention.
[1] http://d.puremagic.com/issues/show_bug.cgi?id=3702
--
Leandro Lucarella (AKA luca) http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Salvajes, de traje, me quieren enseñar
Salvajes, de traje, me quieren educar

The method that I learned from Phobos is not the best, but at least the
function interface reads better:
T gcd(T)(T a, T b)
if (supports_modulus!T)
{
T result;
// ...
return result;
}
That makes it clear that T must support the modulus operation.
Here is how supports_modulus may be defined:
template supports_modulus(T)
{
const bool supports_modulus = is (typeof(
{
T a;
T b;
T c = a % b;
}()));
}
Here are what is at play to get that "named constraint":
- The curly braces after the typeof define a closure (delegate?) literal
- The body includes how the type should be used to satisfy the
'supports_modulus' constraint
- The closure is "executed" with the empty parethesis at the end of it
(actually, not executed at all; because the expression is a parameter to
typeof, which never executes its argument)
- [This is my assumption] typeof produces an invalid type for invalid
expressions
- One of the uses of the 'is' expression produces a bool result if the
type that it receives is not valid
- When a template contains just one definition and that definition
matches the name of the template, the template instantiation is the same
as the definition that it contains. i.e. instead of writing
(supports_modulus!T).supports_modulus
to mean the bool value, one merely writes
supports_modulus!T
A lot of D features! :) But once that code structure is accepted as an
idiom, it works and gives names to constraints.
Ali

it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler can
figure out). This way, the errors can be improved without user
intervention.

How's about optional? Marks an entire function as optional, i.e. will
not be included if it does not compile.
struct foo( T ) {
optional
void bar( ) { // Will not exist if T cannot be flabbergasted.
T tmp;
t.flabbergast( );
}
}
--
Simen

Would it be a bug or a feature if bar was never included? As written, bar
should never compile...

it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler can
figure out). This way, the errors can be improved without user
intervention.

How's about optional? Marks an entire function as optional, i.e. will
not be included if it does not compile.
struct foo( T ) {
optional
void bar( ) { // Will not exist if T cannot be flabbergasted.
T tmp;
t.flabbergast( );
}
}

This can be trivially shown to be NP-complete.
void bar(T)()
{
static if ( big_function!T) {
T t;
t.flabbergast( );
}
}
Compiler cannot determine if T needs flabbergast(), unless it evaluates
big_function. Which can be arbitrarily complicated.
We're taking the approach of making the default error message in such
cases as helpful as possible.

Andrei used that idiom quite extensive in Phobos, unfortunately, I dare to
say. It makes the code a lot harder to read. But the alternative, using
__traits(compiles, ... ) is even worse IMO, because even as is a little
more obvious, is quite verbose.
Something I would like to see with template constraints, is the ability to
show text messages, like when static if is used.
Yao G.
On Sun, 13 Jun 2010 14:36:14 -0500, Leandro Lucarella <llucax gmail.com>
wrote:

Nice article, but when I read:
T gcd(T)(T a, T b)
if (is(typeof(a % b)))
{
...
}
Under the presence of such beauty as template constraint syntax is,
"is(typeof(a % b))" makes my eyes hurt, and my brain wonder. When you
get used to this idiom, it might not look to bad, but I'm seeing people
new to D wonder "why in the hell was that syntax used?" while they try
to decode what is(typeof()) means.
I think is really a shame, all the beauty and clarity gained by the
simple "if" of template constraints, is lost with the cryptic
is(typeof()) (well, maybe not all, but a significant part).
I would love to see this fixed/simplified. For example, by applying the
changes in suggested in bug 3702 [1]. This looks much better, and is
pretty clear to anyone (even people that doesn't know D):
T gcd(T)(T a, T b)
if (meta.compiles(a % b))
{
...
}
I guess at this point this is not going to happen for D2, a real shame
:S
The, the article made me think that, even when template constraints are
useful not only for improving error reporting, they are often used only
for that. Since the compiler knows all the operations a template
parameter will need to satisfy from the function body, it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler can
figure out). This way, the errors can be improved without user
intervention.
[1] http://d.puremagic.com/issues/show_bug.cgi?id=3702

"and a line number pointing into the template body. The error is being
reported as occurring somewhere other than where the actual problem is"
That would be a good place to point out that recent versions of DMD display
template instantiation traces upon template instatiation errors (Does C++ do
that?). Then, of course, it could go on to "but better yet...".
-------------------------------
Not sent from an iPhone.

reported as occurring somewhere other than where the actual problem
is"
That would be a good place to point out that recent versions of DMD
display template instantiation traces upon template instatiation
errors (Does C++ do that?).

"and a line number pointing into the template body. The error is being
reported as occurring somewhere other than where the actual problem is"
That would be a good place to point out that recent versions of DMD display
template instantiation traces upon template instatiation errors (Does C++ do
that?). Then, of course, it could go on to "but better yet...".

I wished to avoid quality of implementation issues, and instead focus on
characteristics of the language.

"and a line number pointing into the template body. The error is being
reported as occurring somewhere other than where the actual problem is"
That would be a good place to point out that recent versions of DMD
display template instantiation traces upon template instatiation
errors (Does C++ do that?). Then, of course, it could go on to "but
better yet...".

I wished to avoid quality of implementation issues, and instead focus on
characteristics of the language.

I think Nick does make a valid point: there is access to the error, it
just takes some more info from the compiler.
Andrei

"and a line number pointing into the template body. The error is being
reported as occurring somewhere other than where the actual problem is"
That would be a good place to point out that recent versions of DMD
display template instantiation traces upon template instatiation errors
(Does C++ do that?). Then, of course, it could go on to "but better
yet...".

I wished to avoid quality of implementation issues, and instead focus on
characteristics of the language.

I think Nick does make a valid point: there is access to the error, it
just takes some more info from the compiler.

My concern was that C++ users (or other non-D-users) might get the mistaken
impression that without constraints, *all* they would get is the unhelpful
"Error: incompatible types for ((a) % (b)): 'int*' and 'int*'", and
re-enforce their belief that templates have an innate tendency to give
useless error messages, and that if you use D, constraints are the only help
you get.
But I may be over-thinking it and worrying about nothing.

When you get used to this idiom, it might not look to bad, but I'm
seeing people new to D wonder "why in the hell was that syntax used?"
while they try to decode what is(typeof()) means.

The syntax doesn't bother me as much as the suggestion to repeat details
of the template's implementation. C++'s concepts were going in this
direction too, adding code that suffers the same problem as
documentation: It can fall out of step with "the real code", and keeping
it aligned requires repeating details that should only be stated once --
in "the real code".
Here we're debating how to state that some type can participate in a
modulus operation, but that we even need to apply this operation to the
function's arguments is an internal detail. It could change after the
first pass at implementing the function, adopting a different algorithm,
and we could wind up continuing to impose requirements on the types that
are no longer relevant to the revised implementation. It looks like yet
another maintenance burden.
--
Steven E. Harris

it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler can
figure out). This way, the errors can be improved without user
intervention.

How's about optional? Marks an entire function as optional, i.e. will
not be included if it does not compile.
struct foo( T ) {
optional
void bar( ) { // Will not exist if T cannot be flabbergasted.
T tmp;
t.flabbergast( );
}
}
--
Simen

it would be nice
to have some sort of way to tell the compiler to write the template
constraints for us (the obvious ones at least, there might be other
template constraints desired besides the ones the ones the compiler

figure out). This way, the errors can be improved without user
intervention.

How's about optional? Marks an entire function as optional, i.e. will
not be included if it does not compile.
struct foo( T ) {
optional
void bar( ) { // Will not exist if T cannot be flabbergasted.
T tmp;
t.flabbergast( );
}
}
--
Simen

Would it be a bug or a feature if bar was never included? As written,
bar should never compile...

Well spotted. And a very good reason not to have this feature (or to
write unit tests, I guess :p )
--
Simen