Is it possible to use tokens as template parameters?

jfondren julian.fondren at gmail.com
Sat Aug 14 20:35:18 UTC 2021


On Saturday, 14 August 2021 at 11:23:12 UTC, rempas wrote:
> Is it possible to do something like that?
>
> ```
> mixin template lel(alias N, alias V) {
>   auto N = V;
> }
>
> void main() {
>   mixin lel!(name, "Hmmmm");
> }
> ```
>
> In this case, it would (if it was possible) get replaced with: 
> `auto name = "Hmmmm";`
> Is there something I'm missing?

When I was learning Rust I kept running into syntaxes like this 
in books and examples. The funny thing was that the latest 
versions of the libraries had all gotten rid of these macros. To 
be able to put something like `mime!(text/html)` in your code 
seemed cool, using Rust's token-based macros, but then it was 
more trouble than it was worth and the fad ended with prejudice.

Your exact usage can be made to work:

```d
enum prop { name, title, location, etc }
enum { name, title, location, etc }

mixin template lel(alias p, alias v) {
     import std.traits : hasMember;

     static assert(hasMember!(prop, p.stringof));
     mixin("auto " ~ p.stringof ~ " = " ~ v.stringof ~ ";");
}

void main() {
     import std.stdio : writeln;

     mixin lel!(name, "Hmmmm");
     writeln(name);
}
```

And how might this be more trouble than it's worth?
1. `name` is always a valid identifier prior to its definition, 
so rearranging your code can result in surprising behavior 
(`writeln(name) // oops this is 0`) without an error, not even a 
complaint about shadowing.
2. `v` is more limited in expression than you might think. For 
example, this fails:

```d
auto x = 2;
mixin lel!(name, &x);  // variable `x` cannot be read at compile 
time
x++;
writeln(*name);        // can only `*` a pointer, not a `int`
```


More information about the Digitalmars-d mailing list