Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 03, 2015 CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Hi, I have now played a around couple of hours (reading everything I could find) to get something to work, but I think I'm missing some basic concepts/understanding. Maybe someone can enlighten me how these things work. I thought that some code from David Nadlinger is what I'm searching for but don't know how to exactly make use of it. Here is the code: I want to filter out some of the "allMembers" and use them in my code for a switch/final to check that call cases that were not filtered are covered. Trying to build the enum for the switch/final statement. auto org_rules = TypeTuple!(__traits(allMembers,BolSource)); static assert(!isTypeTuple!(org_rules)); template startsNotWith(T,char C){ static if (T[0] != C){ enum startsNotWith = true; } else { enum startsNotWith = false; } } template StaticFilter(alias pred, T...) { static if (T.length == 0) { alias TypeTuple!() StaticFilter; } else static if (pred!(T[0])) { alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter; } else { alias StaticFilter!(pred, T[1 .. $]) StaticFilter; } } alias startsNotWithp = startsNotWith!(T,"p"); // doesn't compile: Error: undefined identifier T alias rules = StaticFilter!(startsNotWithp, org_rules); While playing with this a couple of questions came up: 1. How do predicates get their argument(s)? I saw code where only the predicate was mentioned but no arguments. So, I assume there is some behind-the-curtain-magic going on. I read about things like "a == b" where I can reference 'a and 'b in a string. 2. "enum startsNotwith = false" So this is the return syntax for a CTFE for "return(true)" ? 3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well. Or is there a more extensive explanation for the name I don't get? 4. Are there any tutorials about CTFE? This seems to be a very powerful but not so easy to use feature of D, but documentation is quite limited. Thanks a lot. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 03, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Sunday, 3 May 2015 at 21:46:11 UTC, Robert M. Münch wrote: > Hi, I have now played a around couple of hours (reading everything I could find) to get something to work, but I think I'm missing some basic concepts/understanding. Maybe someone can enlighten me how these things work. I thought that some code from David Nadlinger is what I'm searching for but don't know how to exactly make use of it. > > Here is the code: I want to filter out some of the "allMembers" and use them in my code for a switch/final to check that call cases that were not filtered are covered. Trying to build the enum for the switch/final statement. > > auto org_rules = TypeTuple!(__traits(allMembers,BolSource)); > static assert(!isTypeTuple!(org_rules)); > > template startsNotWith(T,char C){ > static if (T[0] != C){ > enum startsNotWith = true; > } else { > enum startsNotWith = false; > } > } Here T would have to be a type. But you want to accept a string. So: ---- template startsNotWith(string s,char c){ enum startsNotWith = s.length == 0 || s[0] != c; } ---- > template StaticFilter(alias pred, T...) { > static if (T.length == 0) { > alias TypeTuple!() StaticFilter; > } else static if (pred!(T[0])) { > alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter; > } else { > alias StaticFilter!(pred, T[1 .. $]) StaticFilter; > } > } > > alias startsNotWithp = startsNotWith!(T,"p"); // doesn't compile: Error: undefined identifier T You need to turn T into a parameter, so that StaticFilter can set it. (And it's really a string again, so I'm renaming to s.) ---- template startsNotWithp(string s) { enum startsNotWithp = startsNotWith!(s, 'p'); } /* Shorthand syntax: enum startsNotWithp(string s) = startsNotWith!(s, 'p'); */ ---- > alias rules = StaticFilter!(startsNotWithp, org_rules); > > > While playing with this a couple of questions came up: > > 1. How do predicates get their argument(s)? I saw code where only the predicate was mentioned but no arguments. So, I assume there is some behind-the-curtain-magic going on. I read about things like "a == b" where I can reference 'a and 'b in a string. Predicates are called/instantiated by the thing to which you pass them. StaticFilter instantiates pred for each element of the T tuple it's given. If some documentation doesn't say how the predicate will be called/instantiated, then it's probably assumed to be obvious. String predicates are turned into functions behind the curtains. The thing you instantiate with "a == b" turns it into `(a, b) {return a == b;}` and uses that. I think we don't do string predicates for templates like StaticFilter, though. > 2. "enum startsNotwith = false" So this is the return syntax for a CTFE for "return(true)" ? It's the template syntax for "return false". CTFE does normal functions at compile time, so there it's just "return false". ---- /* Template: */ template t() {enum t = false;} enum x = t!(); /* CTFE: */ bool f() {return false;} enum y = f(); ---- > 3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well. Yup. And std.traits.isTypeTuple only adds to the confusion. > Or is there a more extensive explanation for the name I don't get? Not that I'm aware of. > 4. Are there any tutorials about CTFE? This seems to be a very powerful but not so easy to use feature of D, but documentation is quite limited. CTFE is rather simple. It just allows you to use certain functions in a static (i.e. compile time) context. Templates are more tricky. If you mean templates, maybe having the right name helps. |
May 03, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Sunday, 3 May 2015 at 21:46:11 UTC, Robert M. Münch wrote: > 3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well. Or is there a more extensive explanation for the name I don't get? Legacy we are trying to get rid of. See also: https://github.com/D-Programming-Language/phobos/pull/3128 https://github.com/D-Programming-Language/dlang.org/pull/986 |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On 4/05/2015 9:46 a.m., Robert M. Münch wrote: > Hi, I have now played a around couple of hours (reading everything I > could find) to get something to work, but I think I'm missing some basic > concepts/understanding. Maybe someone can enlighten me how these things > work. I thought that some code from David Nadlinger is what I'm > searching for but don't know how to exactly make use of it. > > Here is the code: I want to filter out some of the "allMembers" and use > them in my code for a switch/final to check that call cases that were > not filtered are covered. Trying to build the enum for the switch/final > statement. > > auto org_rules = TypeTuple!(__traits(allMembers,BolSource)); > static assert(!isTypeTuple!(org_rules)); > > template startsNotWith(T,char C){ > static if (T[0] != C){ > enum startsNotWith = true; > } else { > enum startsNotWith = false; > } > } > > template StaticFilter(alias pred, T...) { > static if (T.length == 0) { > alias TypeTuple!() StaticFilter; > } else static if (pred!(T[0])) { > alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter; > } else { > alias StaticFilter!(pred, T[1 .. $]) StaticFilter; > } > } > > alias startsNotWithp = startsNotWith!(T,"p"); // doesn't compile: Error: > undefined identifier T > > alias rules = StaticFilter!(startsNotWithp, org_rules); > > > While playing with this a couple of questions came up: > > 1. How do predicates get their argument(s)? I saw code where only the > predicate was mentioned but no arguments. So, I assume there is some > behind-the-curtain-magic going on. I read about things like "a == b" > where I can reference 'a and 'b in a string. > > 2. "enum startsNotwith = false" So this is the return syntax for a CTFE > for "return(true)" ? > > 3. TupleType is a very missleading name when you are learning these > things, because the tuple can hold values as well. Or is there a more > extensive explanation for the name I don't get? > > 4. Are there any tutorials about CTFE? This seems to be a very powerful > but not so easy to use feature of D, but documentation is quite limited. > > Thanks a lot. Have you looked at my book? https://leanpub.com/ctfe |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rikki Cattermole | On 2015-05-04 03:52:21 +0000, Rikki Cattermole said: > Have you looked at my book? https://leanpub.com/ctfe No, thanks for the hint. You will have one more reader ;-) -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On 2015-05-03 23:28:00 +0000, anonymous said: > Here T would have to be a type. But you want to accept a string. So: > ---- > template startsNotWith(string s,char c){ > enum startsNotWith = s.length == 0 || s[0] != c; > } > ---- Hi, ok, just to better understand this (I have a C++ background (even quite old)): When I want to use some functions I need to specify the type? It's not possible to use T.length() which would compile if T is a string? I thought that it's just generic and I can throw in T. >> 1. How do predicates get their argument(s)? I saw code where only the predicate was mentioned but no arguments. So, I assume there is some behind-the-curtain-magic going on. I read about things like "a == b" where I can reference 'a and 'b in a string. > > Predicates are called/instantiated by the thing to which you pass them. StaticFilter instantiates pred for each element of the T tuple it's given. If some documentation doesn't say how the predicate will be called/instantiated, then it's probably assumed to be obvious. Well, and often it's obvious that it's not obvious ;-) > String predicates are turned into functions behind the curtains. The thing you instantiate with "a == b" turns it into `(a, b) {return a == b;}` and uses that. I think we don't do string predicates for templates like StaticFilter, though. Ok, that helps to better understand how this works. Thanks for the feedback. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On 2015-05-03 23:28:00 +0000, anonymous said: > You need to turn T into a parameter, so that StaticFilter can set it. (And it's really a string again, so I'm renaming to s.) > > ---- > template startsNotWithp(string s) > { > enum startsNotWithp = startsNotWith!(s, 'p'); > } > /* Shorthand syntax: enum startsNotWithp(string s) = startsNotWith!(s, 'p'); */ > ---- > >> alias rules = StaticFilter!(startsNotWithp, org_rules); Hi, I have one more questions: Is it possible to write something like this? alias rules = StaticFilter!(startsNotWith(?, 'p'), org_rules); The ? should be used for every memember of org_rules. -- Robert M. Münch http://www.saphirion.com smarter | better | faster |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Monday, 4 May 2015 at 11:22:16 UTC, Robert M. Münch wrote:
> Hi, ok, just to better understand this (I have a C++ background (even quite old)): When I want to use some functions I need to specify the type? It's not possible to use T.length() which would compile if T is a string? I thought that it's just generic and I can throw in T.
In template parameter lists, a solitary identifier is a type parameter. You can only pass types in those.
In function (pointer) declarations, a solitary identifier is the type of the parameter.
In function/delegate literals, a solitary identifier is the name of the parameter and the type is inferred. I guess this is what you were thinking of.
----
void main()
{
template t(T) {} /* T is a template type parameter. */
alias i = t!int; /* It can be instantiated with the type int, for example, */
static assert(!__traits(compiles, t!123)); /* but not with a value. */
void function(int) fp; /* int is the type of the parameter. */
fp = (x) {}; /* x is the name of the parameter whose type is inferred from above. */
}
----
|
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On 4/05/2015 11:15 p.m., Robert M. Münch wrote: > On 2015-05-04 03:52:21 +0000, Rikki Cattermole said: > >> Have you looked at my book? https://leanpub.com/ctfe > > No, thanks for the hint. You will have one more reader ;-) I'm currently live streaming, feel free to jump on and ask any questions! https://www.livecoding.tv/alphaglosined/ |
May 04, 2015 Re: CTFE & template predicates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert M. Münch | On Monday, 4 May 2015 at 11:41:23 UTC, Robert M. Münch wrote:
> Hi, I have one more questions: Is it possible to write something like this?
>
> alias rules = StaticFilter!(startsNotWith(?, 'p'), org_rules);
>
> The ? should be used for every memember of org_rules.
No, we don't have template literals.
|
Copyright © 1999-2021 by the D Language Foundation