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