www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Create an Algebraic type at compile time and more

reply uknys <uknysx pm.me> writes:
Hello,

I wanted to know if such code was possible :

alias Operation = Algebraic!(/* All type that implements X UDA */)

struct X
{
     int opcode;
     Operation h;
}

 X(0x01, Hello(3))
 X(0x02, Hello(4))
struct Hello
{
     int Hello;
}

 X(0x03, Toto(5))
 X(0x05, Toto(6))
struct Toto
{
    int A;
}


It has two problems, Operation not being defined while I use it 
in the UDA, and how to get back all the types that implements 
this UDA to give it to Algebraic.
I don't know if it's a good idea or not, but might as well try 
the dark side of meta programming.

Thanks a lot :)
Jun 14 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 14 June 2018 at 19:15:38 UTC, uknys wrote:
 Hello,

 I wanted to know if such code was possible :

 alias Operation = Algebraic!(/* All type that implements X UDA 
 */)

 struct X
 {
     int opcode;
     Operation h;
 }

  X(0x01, Hello(3))
  X(0x02, Hello(4))
 struct Hello
 {
     int Hello;
 }

  X(0x03, Toto(5))
  X(0x05, Toto(6))
 struct Toto
 {
    int A;
 }


 It has two problems, Operation not being defined while I use it 
 in the UDA, and how to get back all the types that implements 
 this UDA to give it to Algebraic.
 I don't know if it's a good idea or not, but might as well try 
 the dark side of meta programming.

 Thanks a lot :)
First off - Algebraic doesn't work at compile-time[0]: // Error: memcpy cannot be interpreted at compile time, because it has no available source code enum a = Algebraic!(int, string)("Hello!"); Now, as for getting the list of types with an X UDA: import std.traits : getSymbolsByUDA; pragma(msg, getSymbolsByUDA!(mixin(__MODULE__), X)); However, as you sort-of point out, there's a problem of dependencies - if we assign the result of getSymbolsByUDA to a symbol (be that a type or an alias, or part of a type, as in Algebraic!(getSymbolsByUDA)), then getSymbolsByUDA will need to consider that symbol in its search. In order to do that, we need to know more about the type. Theoretically, the compiler might be able to know which UDAs a symbol has without having to figure out all the other details, but such is not currently the case. To get around these issues, maybe you could make Hello and Toto classes instead of structs? -- Simen [0]: https://issues.dlang.org/show_bug.cgi?id=11864
Jun 15 2018
parent reply uknys <uknysx pm.me> writes:
On Friday, 15 June 2018 at 07:27:22 UTC, Simen Kjærås wrote:
 On Thursday, 14 June 2018 at 19:15:38 UTC, uknys wrote:
 [...]
First off - Algebraic doesn't work at compile-time[0]: // Error: memcpy cannot be interpreted at compile time, because it has no available source code enum a = Algebraic!(int, string)("Hello!"); Now, as for getting the list of types with an X UDA: import std.traits : getSymbolsByUDA; pragma(msg, getSymbolsByUDA!(mixin(__MODULE__), X)); However, as you sort-of point out, there's a problem of dependencies - if we assign the result of getSymbolsByUDA to a symbol (be that a type or an alias, or part of a type, as in Algebraic!(getSymbolsByUDA)), then getSymbolsByUDA will need to consider that symbol in its search. In order to do that, we need to know more about the type. Theoretically, the compiler might be able to know which UDAs a symbol has without having to figure out all the other details, but such is not currently the case. To get around these issues, maybe you could make Hello and Toto classes instead of structs? -- Simen [0]: https://issues.dlang.org/show_bug.cgi?id=11864
Yeah I saw that Algebraic doesn't work at compile time, then I thought of using an Interface with one function (execute()) and making Hello and Toto as classes implementing even if that's somewhat slower. Then I could use pragma(msg, getSymbolsByUDA!(mixin(__MODULE__), X)); and make an array sorted by opcode of this interface. Am I right about this ?
Jun 15 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Friday, 15 June 2018 at 10:53:35 UTC, uknys wrote:
 On Friday, 15 June 2018 at 07:27:22 UTC, Simen Kjærås wrote:
 [snip]
Yeah I saw that Algebraic doesn't work at compile time, then I thought of using an Interface with one function (execute()) and making Hello and Toto as classes implementing even if that's somewhat slower. Then I could use pragma(msg, getSymbolsByUDA!(mixin(__MODULE__), X)); and make an array sorted by opcode of this interface. Am I right about this ?
That would be the idea, yes. -- Simen
Jun 15 2018
parent uknys <uknysx pm.me> writes:
On Friday, 15 June 2018 at 12:03:28 UTC, Simen Kjærås wrote:
 On Friday, 15 June 2018 at 10:53:35 UTC, uknys wrote:
 On Friday, 15 June 2018 at 07:27:22 UTC, Simen Kjærås wrote:
 [snip]
Yeah I saw that Algebraic doesn't work at compile time, then I thought of using an Interface with one function (execute()) and making Hello and Toto as classes implementing even if that's somewhat slower. Then I could use pragma(msg, getSymbolsByUDA!(mixin(__MODULE__), X)); and make an array sorted by opcode of this interface. Am I right about this ?
That would be the idea, yes. -- Simen
I found about the sumtype package that does the same thing as Algebraic but also works at compile time, so here is my idea implemented : https://gist.github.com/uknys/dc47a092ff900f8c99f221eda8c9ab42
Jun 16 2018