digitalmars.D.learn - Mixin and imports
- jmh530 (24/24) Jun 07 2020 In the code below, foo!fabs compiles without issue, but
- Mike Parker (6/13) Jun 07 2020 The problem isn't the mixin. It's the template. Templates take
- jmh530 (17/23) Jun 08 2020 Thanks, that makes sense.
- Paul Backus (17/44) Jun 08 2020 If you want to refer to symbols in the scope where the template
- Adam D. Ruppe (6/9) Jun 08 2020 Why do you even want foo!"fabs"? Usually when I see people having
- jmh530 (7/13) Jun 08 2020 There were some other functions in the module that allow the use
- data pulverizer (6/13) Jun 08 2020 Out of curiosity what does the "." in front of `foo` mean? I've
- ag0aep6g (2/6) Jun 08 2020 https://dlang.org/spec/module.html#module_scope_operators
- jmh530 (5/11) Jun 08 2020 ag0aep6g provided the link to it, but it's one of those things
- Steven Schveighoffer (14/28) Jun 08 2020 The dot operator simply specifies that the symbol you are looking for is...
- data pulverizer (4/26) Jun 08 2020 Thanks both of you. It's one of those puzzling things that was at
In the code below, foo!fabs compiles without issue, but foo!"fabs" does not because the import is not available in the string mixin. If I move the import to the top of the module, then it works. However, then if I move foo to another module, then it will no longer compile since it is in different modules. Is there any way I can make sure the mixin knows about the import? I am just using fabs as an example. Ideally, I would want to use any function from any other module. I can figure out how to do it, for instance, if the only functions that were allowed were those in one module, like std.math. ``` double foo(alias f)(double x) { return f(x); } template foo(string f) { mixin("alias foo = .foo!(" ~ f ~ ");"); } void main() { import std.math: fabs; double x = 2.0; double y = foo!fabs(x); double z = foo!"fabs"(x); } ```
Jun 07 2020
On Monday, 8 June 2020 at 02:55:25 UTC, jmh530 wrote:In the code below, foo!fabs compiles without issue, but foo!"fabs" does not because the import is not available in the string mixin. If I move the import to the top of the module, then it works. However, then if I move foo to another module, then it will no longer compile since it is in different modules. Is there any way I can make sure the mixin knows about the import?The problem isn't the mixin. It's the template. Templates take the scope of their declaration, not their instantiation. So the mixin is getting the template's scope. Anyway, this appears to work: `double z = foo!"std.math.fabs"(x);`
Jun 07 2020
On Monday, 8 June 2020 at 04:13:08 UTC, Mike Parker wrote:[snip] The problem isn't the mixin. It's the template. Templates take the scope of their declaration, not their instantiation. So the mixin is getting the template's scope. Anyway, this appears to work: `double z = foo!"std.math.fabs"(x);`Thanks, that makes sense. However, I get the same error with the code below. Am I doing something wrong? double foo(alias f)(double x) { return f(x); } template foo(string f) { mixin("alias foo = .foo!(" ~ f ~ ");"); } void main() { static import std.math; double x = 2.0; double y = foo!(std.math.fabs)(x); double z = foo!"std.math.fabs"(x); }
Jun 08 2020
On Monday, 8 June 2020 at 10:23:24 UTC, jmh530 wrote:On Monday, 8 June 2020 at 04:13:08 UTC, Mike Parker wrote:If you want to refer to symbols in the scope where the template is instantiated, you will have to move the mixin outside of the template: double foo(alias f)(double x) { return f(x); } template foo(string f) { enum foo = "foo!(" ~ f ~ ")"; } void main() { import std.math: fabs; double x = 2.0; double y = foo!(fabs)(x); double z = mixin(foo!"fabs")(x); }[snip] The problem isn't the mixin. It's the template. Templates take the scope of their declaration, not their instantiation. So the mixin is getting the template's scope. Anyway, this appears to work: `double z = foo!"std.math.fabs"(x);`Thanks, that makes sense. However, I get the same error with the code below. Am I doing something wrong? double foo(alias f)(double x) { return f(x); } template foo(string f) { mixin("alias foo = .foo!(" ~ f ~ ");"); } void main() { static import std.math; double x = 2.0; double y = foo!(std.math.fabs)(x); double z = foo!"std.math.fabs"(x); }
Jun 08 2020
On Monday, 8 June 2020 at 10:28:39 UTC, Paul Backus wrote:[snip]Thanks for that suggestion. That works for me. Unfortunately, it's probably not worth the extra effort though, versus doing foo!fabs in my case.
Jun 08 2020
On Monday, 8 June 2020 at 10:41:53 UTC, jmh530 wrote:On Monday, 8 June 2020 at 10:28:39 UTC, Paul Backus wrote:If they are all from std.math you can easily mixin in the template. just import std.math there then it should work. If you want more general arbitrary functions you can get the module of the function by using an alias. Alternatively you can just pass the function itself as an alias or template parameter. There are ways to do what you want but it's kinda hacky. I can't remember the details though. Basically you use mixins and traits to get the module the symbol exists in and then you can use a string mixin to import that module.[snip]Thanks for that suggestion. That works for me. Unfortunately, it's probably not worth the extra effort though, versus doing foo!fabs in my case.
Jun 08 2020
On Monday, 8 June 2020 at 02:55:25 UTC, jmh530 wrote:In the code below, foo!fabs compiles without issue, but foo!"fabs" does not because the import is not available in the string mixin.Why do you even want foo!"fabs"? Usually when I see people having this problem it is actually a misunderstanding of what is possible with the foo!fabs style - which is better in basically every way and can be used in most the same places. So what's your bigger goal?
Jun 08 2020
On Monday, 8 June 2020 at 12:20:46 UTC, Adam D. Ruppe wrote:[snip] Why do you even want foo!"fabs"? Usually when I see people having this problem it is actually a misunderstanding of what is possible with the foo!fabs style - which is better in basically every way and can be used in most the same places. So what's your bigger goal?There were some other functions in the module that allow the use of function!"thinginquotes". However, most of those functions are using the "thinginquotes" to avoid writing function!(SomeEnum.thinginquotes). That really isn't the thing to fix in this case. So I think it makes sense for me to give up what I was trying to do.
Jun 08 2020
On Monday, 8 June 2020 at 02:55:25 UTC, jmh530 wrote:``` ... template foo(string f) { mixin("alias foo = .foo!(" ~ f ~ ");"); } ... ```Out of curiosity what does the "." in front of `foo` mean? I've seen that in some D code on the compiler in GitHub and have no idea what it does. I tried Googling it to no avail. It doesn't have anything to do with UFCS does it? Thanks
Jun 08 2020
On 08.06.20 16:27, data pulverizer wrote:Out of curiosity what does the "." in front of `foo` mean? I've seen that in some D code on the compiler in GitHub and have no idea what it does. I tried Googling it to no avail. It doesn't have anything to do with UFCS does it?https://dlang.org/spec/module.html#module_scope_operators
Jun 08 2020
On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:[snip] Out of curiosity what does the "." in front of `foo` mean? I've seen that in some D code on the compiler in GitHub and have no idea what it does. I tried Googling it to no avail. It doesn't have anything to do with UFCS does it? Thanksag0aep6g provided the link to it, but it's one of those things that has been difficult for me to understand as well. I believe the original code had `foo` in a template. So in that case it was necessary. I'm not sure if it still is in my simplified version.
Jun 08 2020
On 6/8/20 11:11 AM, jmh530 wrote:On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:The dot operator simply specifies that the symbol you are looking for is defined at global scope, so it just changes the lookup rules. Even though it makes the code clearer what foo you are looking at, it was not necessary -- removing the dot works. In some cases it is necessary to use the . lookup rule, because you have another symbol that will be picked first. For example: int x; template bar(string x) { mixin("alias " ~ x ~ " = .x;"); } -Steve[snip] Out of curiosity what does the "." in front of `foo` mean? I've seen that in some D code on the compiler in GitHub and have no idea what it does. I tried Googling it to no avail. It doesn't have anything to do with UFCS does it? Thanksag0aep6g provided the link to it, but it's one of those things that has been difficult for me to understand as well. I believe the original code had `foo` in a template. So in that case it was necessary. I'm not sure if it still is in my simplified version.
Jun 08 2020
On Monday, 8 June 2020 at 16:02:02 UTC, Steven Schveighoffer wrote:On 6/8/20 11:11 AM, jmh530 wrote:Thanks both of you. It's one of those puzzling things that was at the back of mind that has just been resolved.On Monday, 8 June 2020 at 14:27:26 UTC, data pulverizer wrote:The dot operator simply specifies that the symbol you are looking for is defined at global scope, so it just changes the lookup rules. Even though it makes the code clearer what foo you are looking at, it was not necessary -- removing the dot works. In some cases it is necessary to use the . lookup rule, because you have another symbol that will be picked first. For example: int x; template bar(string x) { mixin("alias " ~ x ~ " = .x;"); } -Steve[snip] Out of curiosity what does the "." in front of `foo` mean? [snip]ag0aep6g provided the link to it [snip]
Jun 08 2020