www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Generating unique identifiers at compile time

reply JG <someone somewhere.com> writes:
Hi,

As an experiment I have implemented the following kind of pattern 
matching
(by parsing the part of the string before '=').

```d
struct S {
int x;
int y;
}

struct T {
     int w;
     S s;
}
void main()
{
     mixin(matchAssign(q{auto T(first,S(second,third)) = 
T(1,S(2,3));}));
     first.writeln;  // 1
     second.writeln; // 2
     third.writeln;  // 3
}
```
In doing so I wanted to produce unique identifiers (something 
like gensym in racket.) I did this in a very hacky way:

```d
auto hopefullyUniqueName(size_t n, size_t line=__LINE__) {
     return 
format!"____________________________var___________________________%s%s"(n,line);
}
```

where I pass in the hash of the right hand side in the assignment 
in place of n.

Is there some way to ask the compiler for a unique name or a 
better way of achieving this?
Jun 09 2022
next sibling parent reply user1234 <user1234 12.de> writes:
On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
 Hi,

 As an experiment I have implemented the following kind of 
 pattern matching
 (by parsing the part of the string before '=').

 ```d
 struct S {
 int x;
 int y;
 }

 struct T {
     int w;
     S s;
 }
 void main()
 {
     mixin(matchAssign(q{auto T(first,S(second,third)) = 
 T(1,S(2,3));}));
     first.writeln;  // 1
     second.writeln; // 2
     third.writeln;  // 3
 }
 ```
 In doing so I wanted to produce unique identifiers (something 
 like gensym in racket.) I did this in a very hacky way:

 ```d
 auto hopefullyUniqueName(size_t n, size_t line=__LINE__) {
     return 
 format!"____________________________var___________________________%s%s"(n,line);
 }
 ```

 where I pass in the hash of the right hand side in the 
 assignment in place of n.

 Is there some way to ask the compiler for a unique name or a 
 better way of achieving this?
No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131
Jun 09 2022
next sibling parent reply bauss <jj_1337 live.dk> writes:
On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote:
 
 There's [been attempts] to expose it, exactly so that users can 
 generate unique names, but that did not found its path in the 
 compiler.

 [been attempts]: https://github.com/dlang/dmd/pull/10131
You can generate unique names actually by using CTFE RNG, so it's not really necessary to have it exposed to achieve that. See my hacky example of hidden class members here: https://forum.dlang.org/thread/siczwzlbpikwlevviwxt forum.dlang.org
Jun 09 2022
parent JG <someone somewhere.com> writes:
On Friday, 10 June 2022 at 06:17:54 UTC, bauss wrote:
 On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote:
 
 There's [been attempts] to expose it, exactly so that users 
 can generate unique names, but that did not found its path in 
 the compiler.

 [been attempts]: https://github.com/dlang/dmd/pull/10131
You can generate unique names actually by using CTFE RNG, so it's not really necessary to have it exposed to achieve that. See my hacky example of hidden class members here: https://forum.dlang.org/thread/siczwzlbpikwlevviwxt forum.dlang.org
Thanks for the answers. In my particular I found a way to generate a new depending on the the left hand side.
Jun 12 2022
prev sibling parent reply user1234 <user1234 12.de> writes:
On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote:
 On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
 [...]
No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131
Here's another one. That's nice if people are able to find tricks but there's a need to have a clean way to do that. i.e language feature.
Jun 13 2022
parent user1234 <user1234 12.de> writes:
On Monday, 13 June 2022 at 07:38:54 UTC, user1234 wrote:
 On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote:
 On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
 [...]
No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131
Here's another one. That's nice if people are able to find tricks but there's a need to have a clean way to do that. i.e language feature.
Damnit, forgot [the link] [the link]: https://github.com/dlang/dmd/pull/5633
Jun 13 2022
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
 In doing so I wanted to produce unique identifiers (something 
 like gensym in racket.) I did this in a very hacky way:
[...]
 Is there some way to ask the compiler for a unique name or a 
 better way of achieving this?
Here's a `gensym` implementation I came up with a while back: ```d enum gensym = q{"_gensym" ~ __traits(identifier, {})["__lambda".length .. $]}; // Works multiple times on the same line pragma(msg, mixin(gensym)); pragma(msg, mixin(gensym)); ``` This takes advantage of the fact that the compiler generates a unique identifier for every lambda function it encounters. While you can't actually use those identifiers in your code, they are visible in error messages and can be accessed via `__traits(identifier)`.
Jun 12 2022
parent JG <someone somewhere.com> writes:
On Sunday, 12 June 2022 at 18:45:27 UTC, Paul Backus wrote:
 On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote:
 [...]
[...]
 [...]
Here's a `gensym` implementation I came up with a while back: ```d enum gensym = q{"_gensym" ~ __traits(identifier, {})["__lambda".length .. $]}; // Works multiple times on the same line pragma(msg, mixin(gensym)); pragma(msg, mixin(gensym)); ``` This takes advantage of the fact that the compiler generates a unique identifier for every lambda function it encounters. While you can't actually use those identifiers in your code, they are visible in error messages and can be accessed via `__traits(identifier)`.
Hi, This is great thanks.
Jun 12 2022