Jump to page: 1 2
Thread overview
CTFE & template predicates
May 03, 2015
Robert M. Münch
May 03, 2015
anonymous
May 04, 2015
Robert M. Münch
May 04, 2015
anonymous
May 04, 2015
Robert M. Münch
May 04, 2015
anonymous
May 06, 2015
Per Nordlöw
May 03, 2015
Dicebot
May 04, 2015
Rikki Cattermole
May 04, 2015
Robert M. Münch
May 04, 2015
Rikki Cattermole
May 04, 2015
Robert M. Münch
May 05, 2015
Rikki Cattermole
May 03, 2015
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
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
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
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
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
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
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
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
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
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.
« First   ‹ Prev
1 2