Thread overview
How to use std.meta.Filter?
Apr 21, 2018
Dr.No
Apr 21, 2018
Jonathan M Davis
Apr 21, 2018
Dr.No
Apr 21, 2018
Jonathan M Davis
Apr 22, 2018
Uknown
April 21, 2018
import std.meta : Filter;
enum isNotReservedSymbol(string name) = name != "none" && name != "lastToken";
enum string[] members = staticMembers!Token;
static foreach(member; Filter!(isNotReservedSymbol, members))
{{
		

This return the error:

 Error: template instance `pred!(["none", "word", "n", "digits", "name", /* my whole array here */ ])  does not match template declaration isNotReservedSymbol(string name)

how should have isNotReservedSymbol be defined?
April 21, 2018
On Saturday, April 21, 2018 16:05:22 Dr.No via Digitalmars-d-learn wrote:
> import std.meta : Filter;
> enum isNotReservedSymbol(string name) = name != "none" && name !=
> "lastToken";
> enum string[] members = staticMembers!Token;
> static foreach(member; Filter!(isNotReservedSymbol, members))
> {{
>
>
> This return the error:
>
>   Error: template instance `pred!(["none", "word", "n", "digits",
> "name", /* my whole array here */ ])  does not match template
> declaration isNotReservedSymbol(string name)
>
> how should have isNotReservedSymbol be defined?

std.meta.Filter operates on an AliasSeq, not a dynamic array. If you have an array, then you can just use std.algorithm.iteration.filter with a normal lambda.

- Jonathan M Davis

April 21, 2018
On Saturday, 21 April 2018 at 17:15:47 UTC, Jonathan M Davis wrote:
> On Saturday, April 21, 2018 16:05:22 Dr.No via Digitalmars-d-learn wrote:
>> import std.meta : Filter;
>> enum isNotReservedSymbol(string name) = name != "none" && name !=
>> "lastToken";
>> enum string[] members = staticMembers!Token;
>> static foreach(member; Filter!(isNotReservedSymbol, members))
>> {{
>>
>>
>> This return the error:
>>
>>   Error: template instance `pred!(["none", "word", "n", "digits",
>> "name", /* my whole array here */ ])  does not match template
>> declaration isNotReservedSymbol(string name)
>>
>> how should have isNotReservedSymbol be defined?
>
> std.meta.Filter operates on an AliasSeq, not a dynamic array. If you have an array, then you can just use std.algorithm.iteration.filter with a normal lambda.
>
> - Jonathan M Davis

I've tried use normal filter - albeit i'm willing to do all that at runtin, but I got f cannot be read at compile time.

static foreach(member; staticMembers!Token.filter!(f => isNotReservedSymbol!(member))
April 21, 2018
On Saturday, April 21, 2018 17:46:05 Dr.No via Digitalmars-d-learn wrote:
> On Saturday, 21 April 2018 at 17:15:47 UTC, Jonathan M Davis
>
> wrote:
> > On Saturday, April 21, 2018 16:05:22 Dr.No via
> >
> > Digitalmars-d-learn wrote:
> >> import std.meta : Filter;
> >> enum isNotReservedSymbol(string name) = name != "none" && name
> >> !=
> >> "lastToken";
> >> enum string[] members = staticMembers!Token;
> >> static foreach(member; Filter!(isNotReservedSymbol, members))
> >> {{
> >>
> >> This return the error:
> >>   Error: template instance `pred!(["none", "word", "n",
> >>
> >> "digits",
> >> "name", /* my whole array here */ ])  does not match template
> >> declaration isNotReservedSymbol(string name)
> >>
> >> how should have isNotReservedSymbol be defined?
> >
> > std.meta.Filter operates on an AliasSeq, not a dynamic array. If you have an array, then you can just use std.algorithm.iteration.filter with a normal lambda.
> >
> > - Jonathan M Davis
>
> I've tried use normal filter - albeit i'm willing to do all that at runtin, but I got f cannot be read at compile time.
>
> static foreach(member; staticMembers!Token.filter!(f =>
> isNotReservedSymbol!(member))

Well, it would help if you actually provide an example that I could compile. Based on what you've posted thus far, I assume that staticMembers!Token results in a dynamic array of strings. So, if I have

import std.algorithm.iteration : filter;

enum names = ["none", "word", "n", "digits", "name"];

enum isNotReservedSymbol(string name) = name != "none" &&
                                        name != "lastToken";

static foreach(member; names.filter!(f => isNotReservedSymbol!member))
{
}

void main()
{
}

then I have something similar to what you have, and I get the error

q.d(7): Error: undefined identifier member
/usr/local/include/dmd/std/algorithm/iteration.d(1106):        instantiated
from here: FilterResult!(__lambda6, string[])
q.d(7):        instantiated from here: filter!(string[])

The problem with this is that member is being used on both the left and the right of the foreach. You can't use the iteration variable in what you're iterating. So, I'm guessing that you really meant to use f on the right-hand side of the lambda. In that case, it's

static foreach(member; names.filter!(f => isNotReservedSymbol!f))
{
}

and the error message becomes

q.d(7): Error: variable f cannot be read at compile time
q.d(7):        while looking for match for isNotReservedSymbol!(f)
/usr/local/include/dmd/std/algorithm/iteration.d(1106):        instantiated
from here: FilterResult!(__lambda6, string[])
q.d(7):        instantiated from here: filter!(string[])

And that error message is more like what you mentioned, so I'm guessing that this is what you're hitting. The problem here is that you're mixing up runtime and compile-time constructs. Even though all of this is happening at compile time, there's a difference between a purely compile-time construct and a runtime construct that's run during CTFE. e.g. something like

bool foo(string str)
{
    return isNotReservedSymbol!str;
}

cannot compile, becuase str is a runtime parameter and thus its value is only known at runtime, whereas isNotReservedSymbol is a template, so its argument must be known during compile time - i.e. when the functions is compiled. Using foo with CTFE doesn't change that. foo still needs to compile as if it were going to be used at runtime. The resulting function can then be used at compile time, but it needs to be compiled first. Your lambda has the same problem. Generally, the two options in a case like this are to either turn the parameter into a compile-time parameter or to use a function instead of a template. e.g.

bool foo(string str)()
{
    return isNotReservedSymbol!str;
}

or

bool isNotReservedSymbol(string name)
{
    return name != "none" && name != "lastToken";
}

bool foo(string str)
{
    return isNotReservedSymbol(str);
}

Given that you're operating on a dynamic array of strings, there's really no reason to declare templates to operate on it. Stuff like std.meta.Filter is for cases where you need to use an AliasSeq, which _usually_ means that you're dealing with actual symbols and not values (occasionally, it can make sense to use an AliasSeq with values, but that's usually only if they're not the same type or if the AliasSeq contains a mix of types and values, since if an AliasSeq containts values of the same type, you can always just put [] around the AliasSeq to get a dynamic array of its values). So, I'd suggest that you simply make isNotReservedSymbol a function. And then you get something like

import std.algorithm.iteration : filter;

enum names = ["none", "word", "n", "digits", "name"];

bool isNotReservedSymbol(string name)
{
    return name != "none" && name != "lastToken";
}

static foreach(member; names.filter!(f => isNotReservedSymbol(f)))
{
}

void main()
{
}

and that compiles.

- Jonathan M Davis

April 22, 2018
On Saturday, 21 April 2018 at 17:46:05 UTC, Dr.No wrote:
> On Saturday, 21 April 2018 at 17:15:47 UTC, Jonathan M Davis wrote:
>> On Saturday, April 21, 2018 16:05:22 Dr.No via Digitalmars-d-learn wrote:
>>> import std.meta : Filter;
>>> enum isNotReservedSymbol(string name) = name != "none" && name !=
>>> "lastToken";
>>> enum string[] members = staticMembers!Token;
>>> static foreach(member; Filter!(isNotReservedSymbol, members))
>>> {{
>>>
>>>
>>> This return the error:
>>>
>>>   Error: template instance `pred!(["none", "word", "n", "digits",
>>> "name", /* my whole array here */ ])  does not match template
>>> declaration isNotReservedSymbol(string name)
>>>
>>> how should have isNotReservedSymbol be defined?
>>
>> std.meta.Filter operates on an AliasSeq, not a dynamic array. If you have an array, then you can just use std.algorithm.iteration.filter with a normal lambda.
>>
>> - Jonathan M Davis
>
> I've tried use normal filter - albeit i'm willing to do all that at runtin, but I got f cannot be read at compile time.
>
> static foreach(member; staticMembers!Token.filter!(f => isNotReservedSymbol!(member))

If you are confused by why some things work during compilation and others don't, I would encourage you to read https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
Its a nice article explaining how there are two "compile-time" steps where code can be executed.
April 21, 2018
On 4/21/18 1:46 PM, Dr.No wrote:
> On Saturday, 21 April 2018 at 17:15:47 UTC, Jonathan M Davis wrote:
>> On Saturday, April 21, 2018 16:05:22 Dr.No via Digitalmars-d-learn wrote:
>>> import std.meta : Filter;
>>> enum isNotReservedSymbol(string name) = name != "none" && name !=
>>> "lastToken";
>>> enum string[] members = staticMembers!Token;
>>> static foreach(member; Filter!(isNotReservedSymbol, members))
>>> {{
>>>
>>>
>>> This return the error:
>>>
>>>   Error: template instance `pred!(["none", "word", "n", "digits",
>>> "name", /* my whole array here */ ])  does not match template
>>> declaration isNotReservedSymbol(string name)
>>>
>>> how should have isNotReservedSymbol be defined?
>>
>> std.meta.Filter operates on an AliasSeq, not a dynamic array. If you have an array, then you can just use std.algorithm.iteration.filter with a normal lambda.
>>
> 
> I've tried use normal filter - albeit i'm willing to do all that at runtin, but I got f cannot be read at compile time.
> 
> static foreach(member; staticMembers!Token.filter!(f => isNotReservedSymbol!(member))

Filter probably should work on arrays readable at compile time. I bet it just hasn't been updated since static foreach was introduced.

-Steve