digitalmars.D - Is it possible to use tokens as template parameters?
- rempas (12/12) Aug 14 2021 Is it possible to do something like that?
- Tejas (13/25) Aug 14 2021 You have to use mixins to achieve the desired effect.
- rempas (3/31) Aug 14 2021 The behavior I want to achieve is not having to enclose the word
- evilrat (13/15) Aug 14 2021 Then it is not possible. D is strictly hygienic in that regard.
- Alexandru Ermicioi (7/9) Aug 14 2021 The closest you can get is using q{mixed d code} syntax that is
- rempas (4/13) Aug 14 2021 I mean I don't... But I was just curious if that's possible.
- jfondren (36/48) Aug 14 2021 When I was learning Rust I kept running into syntaxes like this
- rempas (3/13) Aug 14 2021 Makes sense. I also thought that Rust's macro_rules! were cool
- Daniel N (21/24) Aug 15 2021 opDispatch can create strings, which can either be directly mixed
- =?UTF-8?Q?Ali_=c3=87ehreli?= (14/17) Aug 16 2021 I sometimes wish templates had opDispatch abilities. Then we could
- Steven Schveighoffer (17/42) Aug 16 2021 Well, aliases do work with operators, so....
- =?UTF-8?Q?Ali_=c3=87ehreli?= (8/22) Aug 16 2021 Me no understand. :) I see it as an example of how opDispatch is
- Steven Schveighoffer (5/33) Aug 16 2021 Well, I mean it's just `.` instead of `!`. What's the big deal? ;)
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?
Aug 14 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?You have to use mixins to achieve the desired effect. ```d mixin template lel(T, string N, string V) { mixin(T.stringof ~ " " ~N ~ " = " ~ V ~ ";"); } import std; void main(){ mixin lel!(string, "name", ` "hmmmm" `); writeln(name); } } ```
Aug 14 2021
On Saturday, 14 August 2021 at 12:19:59 UTC, Tejas wrote:On Saturday, 14 August 2021 at 11:23:12 UTC, rempas wrote:The behavior I want to achieve is not having to enclose the word (tokens) in double quotes.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?You have to use mixins to achieve the desired effect. ```d mixin template lel(T, string N, string V) { mixin(T.stringof ~ " " ~N ~ " = " ~ V ~ ";"); } import std; void main(){ mixin lel!(string, "name", ` "hmmmm" `); writeln(name); } } ```
Aug 14 2021
On Saturday, 14 August 2021 at 13:50:52 UTC, rempas wrote:The behavior I want to achieve is not having to enclose the word (tokens) in double quotes.Then it is not possible. D is strictly hygienic in that regard. You either use explicit mixin or string paramter. It is possible to have it with alias by using std.meta ```Alias!"name_here"``` or similar short template like below, but both has same limitation, there is absolutely no way to get rid of quotes. ```d auto t(T) { enum t = T; } writeln("token".t); ```
Aug 14 2021
On Saturday, 14 August 2021 at 13:50:52 UTC, rempas wrote:The behavior I want to achieve is not having to enclose the word (tokens) in double quotes.The closest you can get is using q{mixed d code} syntax that is basically a string containing d code, and hence subject to some checkups, and ide highlighting. Though why do you need this? Regards, Alexandru
Aug 14 2021
On Saturday, 14 August 2021 at 15:21:51 UTC, Alexandru Ermicioi wrote:On Saturday, 14 August 2021 at 13:50:52 UTC, rempas wrote:I mean I don't... But I was just curious if that's possible. Using a constant would probably also work I guess.The behavior I want to achieve is not having to enclose the word (tokens) in double quotes.The closest you can get is using q{mixed d code} syntax that is basically a string containing d code, and hence subject to some checkups, and ide highlighting. Though why do you need this? Regards, Alexandru
Aug 14 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` ```
Aug 14 2021
On Saturday, 14 August 2021 at 20:35:18 UTC, jfondren wrote:On Saturday, 14 August 2021 at 11:23:12 UTC, rempas wrote:Makes sense. I also thought that Rust's macro_rules! were cool but I understand your point. Thanks a lot![...]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. [...]
Aug 14 2021
On Sunday, 15 August 2021 at 05:47:34 UTC, rempas wrote:opDispatch can create strings, which can either be directly mixed in, or the generated string can be send to mixin templates. ```d import std; static struct Yay { string opDispatch(string name, T...)(T vals) { return q{ auto %s = 777; }.format(name); } } enum yay=Yay(); void main() { mixin(yay.magic); magic.writeln; } ```[...]Makes sense. I also thought that Rust's macro_rules! were cool but I understand your point. Thanks a lot!
Aug 15 2021
On 8/15/21 1:40 AM, Daniel N wrote:static struct Yay { string opDispatch(string name, T...)(T vals)I sometimes wish templates had opDispatch abilities. Then we could instantiate a template with a symbol and the the template could receive it as string just like the way it works for opDispatch. So, this could work: Flag!isCool isCool; instead of today's Flag!"isCool" isCool; Basically, it would still be a string parameter but the quotes need not be provided: template Flag(string tag) { // ... } I realize that this might hide some bugs but so does opDispatch, no? Ali
Aug 16 2021
On 8/16/21 1:59 PM, Ali Çehreli wrote:On 8/15/21 1:40 AM, Daniel N wrote: > static struct Yay > { > string opDispatch(string name, T...)(T vals) I sometimes wish templates had opDispatch abilities. Then we could instantiate a template with a symbol and the the template could receive it as string just like the way it works for opDispatch. So, this could work: Flag!isCool isCool; instead of today's Flag!"isCool" isCool; Basically, it would still be a string parameter but the quotes need not be provided: template Flag(string tag) { // ... } I realize that this might hide some bugs but so does opDispatch, no?Well, aliases do work with operators, so.... ```d import std.typecons; struct S { alias opDispatch(string foo) = Flag!foo; } void main() { S.bar x; import std.traits; pragma(msg, fullyQualifiedName!(typeof(x))); // std.typecons.Flag!("bar") } ``` -Steve
Aug 16 2021
On 8/16/21 12:37 PM, Steven Schveighoffer wrote:```d import std.typecons; struct S { alias opDispatch(string foo) = Flag!foo; } void main() { S.bar x; import std.traits; pragma(msg, fullyQualifiedName!(typeof(x))); // std.typecons.Flag!("bar") } ```Me no understand. :) I see it as an example of how opDispatch is privileged. It nicely parses a token and provides it as a string. Templates don't have that. I want to be able say std.typecons.Flag!foo f; instead of std.typecons.Flag!"foo" f; Ali
Aug 16 2021
On 8/16/21 5:45 PM, Ali Çehreli wrote:On 8/16/21 12:37 PM, Steven Schveighoffer wrote: > ```d > import std.typecons; > > struct S > { > alias opDispatch(string foo) = Flag!foo; > } > > void main() > { > S.bar x; > import std.traits; > pragma(msg, fullyQualifiedName!(typeof(x))); // > std.typecons.Flag!("bar") > } > ``` Me no understand. :) I see it as an example of how opDispatch is privileged. It nicely parses a token and provides it as a string. Templates don't have that. I want to be able say std.typecons.Flag!foo f; instead of std.typecons.Flag!"foo" f;Well, I mean it's just `.` instead of `!`. What's the big deal? ;) Honestly, I didn't expect this to work when I tried it, but I did know that aliases do work with operator overloads (a hugely cool feature). -Steve
Aug 16 2021