Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 08, 2020 Mixin and imports | ||||
---|---|---|---|---|
| ||||
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); } ``` |
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | 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);`
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | 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);
}
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | 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:
>> [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);
> }
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);
}
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | 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.
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | 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?
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | 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:
>> [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.
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.
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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. |
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | 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
|
June 08, 2020 Re: Mixin and imports | ||||
---|---|---|---|---|
| ||||
Posted in reply to data pulverizer | 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 |
Copyright © 1999-2021 by the D Language Foundation