digitalmars.D - Templates with scope
- bauss (51/51) Jul 21 2021 Is there a way to make this logic work without using a mixin
- bauss (1/2) Jul 21 2021 This was meant to be in learn...
- =?UTF-8?Q?S=c3=b6nke_Ludwig?= (8/12) Jul 21 2021 The symbol name is not available in the scope of the template, so that
- bauss (23/37) Jul 21 2021 The problem is that I just saw I didn't describe my problem very
- bauss (6/46) Jul 21 2021 I found a somewhat solution to it all by creating a template that
- drug (26/26) Jul 21 2021 But why do you think that `CanCompile` fails? It works for me:
- Paul Backus (13/18) Jul 21 2021 ```d
Is there a way to make this logic work without using a mixin
template.
I'd prefer if using a plain template was possible, rather than
using a mixin template, because it introduces some extra
boilerplate.
```d
template CanCompile(alias symbol)
{
enum CanCompile = __traits(compiles, { mixin(symbol.stringof
~ " = 10;"); });
}
mixin template CanCompile2(alias symbol)
{
enum couldCompile = __traits(compiles, {
mixin(symbol.stringof ~ " = 10;"); });
}
void main()
{
int x = 20;
// Fails:
static if (CanCompile!x)
{
x = 10;
}
// Okay:
mixin CanCompile2!x;
static if (couldCompile)
{
x -= 10;
}
writeln(x); // Output: 10
}
```
If it was possible to do it like this:
```d
static if (mixin CanCompile2!x)
{
x -= 10;
}
```
Then it wouldn't be a problem, but unfortunately it's not.
I know why the template fails, so I'm not looking for the
reasoning behind it, but is there not a way to avoid using mixin
templates because I don't want to introduce a variable into the
scope and I want to keep the code as short as possible.
Basically my use-case is just to test if certain expressions are
possible in the current scope based on a given symbol, but I'd
want to just test it in a static if statement.
I'm aware that I can just put the __traits(compiles) directly
into the code, but what I'm trying to achieve here is a wrapper
around that so I don't have some ugly boilerplate code.
Jul 21 2021
Am 21.07.2021 um 09:16 schrieb bauss:Is there a way to make this logic work without using a mixin template. I'd prefer if using a plain template was possible, rather than using a mixin template, because it introduces some extra boilerplate.The symbol name is not available in the scope of the template, so that the `mixin(symbol.stringof)` doesn't work, but you can simply use the alias directly: template CanCompile(alias symbol) { enum CanCompile = __traits(compiles, { symbol = 10; }); }
Jul 21 2021
On Wednesday, 21 July 2021 at 09:06:52 UTC, Sönke Ludwig wrote:Am 21.07.2021 um 09:16 schrieb bauss:The problem is that I just saw I didn't describe my problem very well, as I don't actually have the symbol at the given time. I only had the symbol name and I use it to test if the symbol is available because it comes from a __traits(allMembers) which includes some symbols that makes it fail to compile if I try to use the symbol directly without checking whether it compiles or not. And this was the exact template I was trying to use: ```d template CanUseSymbol(string symbolName, string symbolAlias = "symbol", string moduleAlias = "moduleImport") { enum CanUseSymbol = __traits(compiles, { mixin("alias " ~ symbolAlias ~ " = " ~ moduleAlias ~ "." ~ symbolName ~ ";"); }); } ``` For obvious reasons it doesn't work as you also mentioned, the scope simply isn't available. But I can't use alias unfortunately in this case. I wish there was a way to return the symbols from allMembers, instead of just the name of the symbols, that would solve this problem.Is there a way to make this logic work without using a mixin template. I'd prefer if using a plain template was possible, rather than using a mixin template, because it introduces some extra boilerplate.The symbol name is not available in the scope of the template, so that the `mixin(symbol.stringof)` doesn't work, but you can simply use the alias directly: template CanCompile(alias symbol) { enum CanCompile = __traits(compiles, { symbol = 10; }); }
Jul 21 2021
On Wednesday, 21 July 2021 at 10:08:10 UTC, bauss wrote:On Wednesday, 21 July 2021 at 09:06:52 UTC, Sönke Ludwig wrote:I found a somewhat solution to it all by creating a template that used __traits(allMembers) and in the same scope tested the members and built a new list of members that were available and then simply used the generated list to loop through, so I didn't have to test the symbols outside of the template's scope.Am 21.07.2021 um 09:16 schrieb bauss:The problem is that I just saw I didn't describe my problem very well, as I don't actually have the symbol at the given time. I only had the symbol name and I use it to test if the symbol is available because it comes from a __traits(allMembers) which includes some symbols that makes it fail to compile if I try to use the symbol directly without checking whether it compiles or not. And this was the exact template I was trying to use: ```d template CanUseSymbol(string symbolName, string symbolAlias = "symbol", string moduleAlias = "moduleImport") { enum CanUseSymbol = __traits(compiles, { mixin("alias " ~ symbolAlias ~ " = " ~ moduleAlias ~ "." ~ symbolName ~ ";"); }); } ``` For obvious reasons it doesn't work as you also mentioned, the scope simply isn't available. But I can't use alias unfortunately in this case. I wish there was a way to return the symbols from allMembers, instead of just the name of the symbols, that would solve this problem.Is there a way to make this logic work without using a mixin template. I'd prefer if using a plain template was possible, rather than using a mixin template, because it introduces some extra boilerplate.The symbol name is not available in the scope of the template, so that the `mixin(symbol.stringof)` doesn't work, but you can simply use the alias directly: template CanCompile(alias symbol) { enum CanCompile = __traits(compiles, { symbol = 10; }); }
Jul 21 2021
But why do you think that `CanCompile` fails? It works for me:
```D
template CanCompile(alias symbol)
{
enum CanCompile = __traits(compiles, { symbol = 10; });
}
mixin template CanCompile2(alias symbol)
{
enum couldCompile = __traits(compiles, { symbol = 10; });
}
void main()
{
int x = 20;
static if (CanCompile!x)
{
x = 9;
}
assert(x == 9);
mixin CanCompile2!x;
static if (couldCompile)
{
x = 12;
}
assert(x == 12);
}
```
Jul 21 2021
On Wednesday, 21 July 2021 at 07:16:43 UTC, bauss wrote:Is there a way to make this logic work without using a mixin template. I'd prefer if using a plain template was possible, rather than using a mixin template, because it introduces some extra boilerplate.```d enum CanCompile(alias symbol) = `__traits(compiles, { ` ~ symbol.stringof ~ ` = 10; })`; void main() { int x = 20; static if (mixin(CanCompile!x)) { x = 10; } } ```
Jul 21 2021









bauss <jj_1337 live.dk> 