digitalmars.D - Template metaprogramming quirk list
- Don Clugston (94/94) Jan 17 2006 The items in this list mostly fall into the category of limitations
- Georg Wrede (17/133) Jan 19 2006 This is drastically different from what I've been (all year) talking
- Sean Kelly (5/10) Jan 20 2006 I've run into most of the problems Don describes and I agree with all of...
- Walter Bright (7/11) Jan 21 2006 On the 17th and 18th I attended a conference, and on the 18th I was givi...
- Georg Wrede (2/16) Jan 22 2006 Cool!!!
- Chris Lajoie (4/5) Jan 20 2006 signed. most of these seem like relatively minor things but I would
The items in this list mostly fall into the category of limitations
rather than bugs; but in each case, the limitations are unintuitive.
I've listed them in order of decreasing importance.
Workarounds are also shown.
---------------------
MAJOR: Restrictions on static if in templates
Quoting the docs:
"StaticIfConditions cannot appear at module scope. They can appear in
class, template, struct, union, or function scope. In function scope,
the symbols referred to in the AssignExpression can be any that can
normally be referenced by an expression at that point. Otherwise, the
only symbols that can be referred to are up one scope level from the
condition."
...
"It does not introduce a new scope even if { } are used for
conditionally compiled statements."
Together, these restrictions mean that a metafunction can't store
intermediate results, so that complex template code like pragma's regex
gets quite ugly and convoluted.
Workaround: invoke the metafunction every time you want to use the
result from it. (Sometimes this can result in a drastic increase in
the number of template instantiations required).
---------------------
MINOR: Allow concatenation char[] ~ char
Desired:
const char [] s = "abcdef" ~ 'g';
Workaround: Ugly. Convert char to char[] by taking slices of a string
containing all characters. Only works for char, not for wchar, dchar.
const char [] s = "abcdef" ~ makechar!('g');
/// converts a single char to a char[]
template makechar(int c)
{
const char [] makechar=
x"000102030405060708090a0b0c0d0e0f
101112131415161718191a1b1c1d1e1f
202122232425262728292a1b2c2d2e2f
303132333435363738393a3b3c3d3e3f
404142434445464748494a4b4c4d4e4f
505152535455565758595a5b5c5d5e5f
606162636465666768696a6b6c6d6e6f
707172737475767778797a7b7c7d7e7f
808182838485868788898a8b8c8d8e8f
909192939495969798999a9b9c9d9e9f
a0a1a2a3a4a5a6a7a8a9aaabacadaeaf
b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
e0e1e2e3e4e5e6e7e8e9eaebecedeeef
f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"[c..c+1];
}
---------------------
AESTHETIC: The . in recursive templates.
template fact(int x)
{
static if (x>1) const int fact = x * .fact!(x-1);
else const int fact = 1;
}
The dot is a workaround, only needed because the constant "fact" we're
setting is in scope.
Why is it already in the symbol table? The workaround is more complex
when the template is not at module scope -- you need to include dot plus
fully qualified name. The following example works:
struct outer
{
template fact(int x)
{
static if (x>1) const int fact = x * .outer.fact!(x-1);
else const int fact = 1;
}
static assert(fact!(6)==8);
}
If you leave off the dot before the outer, ie
static if (x>1) const int fact = x * outer.fact!(x-1);
then the error message is:
template fact!(x - 1) is not a member of outer
which is a little weird.
---------------------
MINOR: Allow compile time equality comparisions char[] == char[], char[]
!= char[]
This would be a problem if the workaround was not so easy.
// return true if str1 == str2
template streq(char [] str1, char[] str2)
{
static if (str1.length!=str2.length) const bool streq=false;
else static if (str1[0]!=str2[0]) const bool streq=false;
else static if (str1.length==1) const bool streq=true;
else const bool streq = .streq!(str1[1..str1.length],
str2[1..str2.length]);
}
---------------------
AESTHETIC: Allow $ as a compile time constant
You can always use .length instead, so it's never really a problem.
Previously reported as a bug (digitalmars.com digitalmars.D.bugs:5977);
could be considered to be a limitation instead.
Jan 17 2006
Don Clugston wrote:
The items in this list mostly fall into the category of limitations
rather than bugs; but in each case, the limitations are unintuitive.
I've listed them in order of decreasing importance.
Workarounds are also shown.
---------------------
MAJOR: Restrictions on static if in templates
Quoting the docs:
"StaticIfConditions cannot appear at module scope. They can appear in
class, template, struct, union, or function scope. In function scope,
the symbols referred to in the AssignExpression can be any that can
normally be referenced by an expression at that point. Otherwise, the
only symbols that can be referred to are up one scope level from the
condition."
...
"It does not introduce a new scope even if { } are used for
conditionally compiled statements."
Together, these restrictions mean that a metafunction can't store
intermediate results, so that complex template code like pragma's regex
gets quite ugly and convoluted.
Workaround: invoke the metafunction every time you want to use the
result from it. (Sometimes this can result in a drastic increase in
the number of template instantiations required).
---------------------
MINOR: Allow concatenation char[] ~ char
Desired:
const char [] s = "abcdef" ~ 'g';
Workaround: Ugly. Convert char to char[] by taking slices of a string
containing all characters. Only works for char, not for wchar, dchar.
const char [] s = "abcdef" ~ makechar!('g');
/// converts a single char to a char[]
template makechar(int c)
{
const char [] makechar=
x"000102030405060708090a0b0c0d0e0f
101112131415161718191a1b1c1d1e1f
202122232425262728292a1b2c2d2e2f
303132333435363738393a3b3c3d3e3f
404142434445464748494a4b4c4d4e4f
505152535455565758595a5b5c5d5e5f
606162636465666768696a6b6c6d6e6f
707172737475767778797a7b7c7d7e7f
808182838485868788898a8b8c8d8e8f
909192939495969798999a9b9c9d9e9f
a0a1a2a3a4a5a6a7a8a9aaabacadaeaf
b0b1b2b3b4b5b6b7b8b9babbbcbdbebf
c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
e0e1e2e3e4e5e6e7e8e9eaebecedeeef
f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"[c..c+1];
}
---------------------
AESTHETIC: The . in recursive templates.
template fact(int x)
{
static if (x>1) const int fact = x * .fact!(x-1);
else const int fact = 1;
}
The dot is a workaround, only needed because the constant "fact" we're
setting is in scope.
Why is it already in the symbol table? The workaround is more complex
when the template is not at module scope -- you need to include dot plus
fully qualified name. The following example works:
struct outer
{
template fact(int x)
{
static if (x>1) const int fact = x * .outer.fact!(x-1);
else const int fact = 1;
}
static assert(fact!(6)==8);
}
If you leave off the dot before the outer, ie
static if (x>1) const int fact = x * outer.fact!(x-1);
then the error message is:
template fact!(x - 1) is not a member of outer
which is a little weird.
---------------------
MINOR: Allow compile time equality comparisions char[] == char[], char[]
!= char[]
This would be a problem if the workaround was not so easy.
// return true if str1 == str2
template streq(char [] str1, char[] str2)
{
static if (str1.length!=str2.length) const bool streq=false;
else static if (str1[0]!=str2[0]) const bool streq=false;
else static if (str1.length==1) const bool streq=true;
else const bool streq = .streq!(str1[1..str1.length],
str2[1..str2.length]);
}
---------------------
AESTHETIC: Allow $ as a compile time constant
You can always use .length instead, so it's never really a problem.
Previously reported as a bug (digitalmars.com digitalmars.D.bugs:5977);
could be considered to be a limitation instead.
This is drastically different from what I've been (all year) talking
about. Still, the way Don puts it, I've a hard time figuring out why
_not_ do this like he proposes.
Of course, the difference (or should I say "_the_ difference" between me
and Don is, he's more Politically Correct, more Socially Adept, etc. (No
disrespect to Don.))
I tend to pursue issues I feel intuitively deserve the attention, while
Don is Diligent (meaning: by the time he suggests something, there is
_no_way_ anybody could kick the suggestion in the knee).
---
The message (above), to which I'm responding, is written on the 17th,
while right now it is the 20th. Considering the respect Don deserves,
even a "I've read it, let's see, we'll be back" response would be more
appropiate than just silence.
((((( I must be getting in the Meno Pause Age here, but hey, such
affected women don't acknowledge that either! ))))))
Jan 19 2006
Georg Wrede wrote:The message (above), to which I'm responding, is written on the 17th, while right now it is the 20th. Considering the respect Don deserves, even a "I've read it, let's see, we'll be back" response would be more appropiate than just silence.I've run into most of the problems Don describes and I agree with all of his suggestions. I hadn't replied until now mostly because I generally avoid "me too" posts, but perhaps it woul help in this case :-) Sean
Jan 20 2006
"Georg Wrede" <georg.wrede nospam.org> wrote in message news:43D05AF5.7030904 nospam.org...The message (above), to which I'm responding, is written on the 17th, while right now it is the 20th. Considering the respect Don deserves, even a "I've read it, let's see, we'll be back" response would be more appropiate than just silence.On the 17th and 18th I attended a conference, and on the 18th I was giving a presentation. So that consumed all my time. On the evening of the 18th, I left for a brief business trip and just got back. So as for what Don's message deserves, the problems have all been corrected and will go out in the next update.
Jan 21 2006
Walter Bright wrote:"Georg Wrede" <georg.wrede nospam.org> wrote in message news:43D05AF5.7030904 nospam.org...Cool!!!The message (above), to which I'm responding, is written on the 17th, while right now it is the 20th. Considering the respect Don deserves, even a "I've read it, let's see, we'll be back" response would be more appropiate than just silence.On the 17th and 18th I attended a conference, and on the 18th I was giving a presentation. So that consumed all my time. On the evening of the 18th, I left for a brief business trip and just got back. So as for what Don's message deserves, the problems have all been corrected and will go out in the next update.
Jan 22 2006
Don Clugston wrote:[everything Don said]signed. most of these seem like relatively minor things but I would personally consider them bugs that should be "fixed". Chris
Jan 20 2006









Sean Kelly <sean f4.ca> 