www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: reflective enums

reply renoX <renosky free.fr> writes:
Kevin Bealer Wrote:

 renoX wrote:
 Kevin Bealer a écrit :
 == Quote from renoX (renosky free.fr)'s article
 - why the name getString instead of the usual toString name?

That could be changed too; I think of toString() as an object method, and when adding a static method, I figured I should use a different name to avoid conflicting with the method. I didn't really check whether there is a real conflict on this.

From my testing, it doesn't trigger a conflict, but I've only tested it inside one file.
 There is kind of a strangeness with the way I defined this in that you
 creating instances of the Enum!(...) struct is not useful.  The type is
 only really interesting for its static properties.

About this I was wondering if it wouldn't be less strange to do a template like this: // expected usage: DefEnum!("enum ListEnumFoo {A,B=1};") template DefEnum(char[] def_enum) { mixin(def_enum); static toString(EnumType!(def_enum) x) { // function body similar to the inital get_String() } } Advantages: -The reflective enum type is really an enum type, so it acts like one. -No weird struct. -When(If) I can convince Walther that writef("foo %s",x) means really writef("foo "~x.toString()); we could write: writef("enum x value is %d and name is %s\n",x,x); and have the correct result, because toString(ListEnumFoo x) would hide toString(int x) {x being an enum variable from type ListEnumFoo). Disadvantage: No easy way to iterate among the enum values: we cannot do foreach(v; ListEnumFoo) because now ListEnumFoo is an enum not a struct.. And we cannot pass an enum type as a parameter, other it would be easy to define function 'keys' and 'values' (like for associative arrays), so we'd need a dummy parameter, i.e you wouldn't be able to write foreach (v; ListEnumFoo) {} and neither foreach (v; ListEnumFoo.values()) {} but foreach (v; ListEnumFoo.A.values()) {} could perhaps work. What do you think about this other way to do it? Regards, renoX

I don't like the extra syntax -- in your example, the word 'enum' appears three times.

This is easy to fix..
 I also like the ability to foreach() over an enum. 
 But this has made me think of another idea that adds some of the 
 "enum"-ness back to the struct.  I'll post it if I can make it work. 
 Kevin

How about we discuss our usecase first, then we could work on the API for declaration, use, print and foreach. Given our initial work as a basis, the implementation then should be easy either using templates or compile-time functions (I've seen your implementation and I must admit that I'm a bit disappointed that it doesn't look that much better than the one which used templates). I'll open a new thread so that the discussion about the design is seen by everyone, hopefully some will contribute. renoX
Feb 19 2007
parent Kevin Bealer <kevinbealer gmail.com> writes:
renoX wrote:
 Kevin Bealer Wrote:
 
 renoX wrote:
 Kevin Bealer a écrit :
 == Quote from renoX (renosky free.fr)'s article
 - why the name getString instead of the usual toString name?

when adding a static method, I figured I should use a different name to avoid conflicting with the method. I didn't really check whether there is a real conflict on this.

inside one file.
 There is kind of a strangeness with the way I defined this in that you
 creating instances of the Enum!(...) struct is not useful.  The type is
 only really interesting for its static properties.

template like this: // expected usage: DefEnum!("enum ListEnumFoo {A,B=1};") template DefEnum(char[] def_enum) { mixin(def_enum); static toString(EnumType!(def_enum) x) { // function body similar to the inital get_String() } } Advantages: -The reflective enum type is really an enum type, so it acts like one. -No weird struct. -When(If) I can convince Walther that writef("foo %s",x) means really writef("foo "~x.toString()); we could write: writef("enum x value is %d and name is %s\n",x,x); and have the correct result, because toString(ListEnumFoo x) would hide toString(int x) {x being an enum variable from type ListEnumFoo). Disadvantage: No easy way to iterate among the enum values: we cannot do foreach(v; ListEnumFoo) because now ListEnumFoo is an enum not a struct.. And we cannot pass an enum type as a parameter, other it would be easy to define function 'keys' and 'values' (like for associative arrays), so we'd need a dummy parameter, i.e you wouldn't be able to write foreach (v; ListEnumFoo) {} and neither foreach (v; ListEnumFoo.values()) {} but foreach (v; ListEnumFoo.A.values()) {} could perhaps work. What do you think about this other way to do it? Regards, renoX

appears three times.

This is easy to fix..
 I also like the ability to foreach() over an enum. 
 But this has made me think of another idea that adds some of the 
 "enum"-ness back to the struct.  I'll post it if I can make it work. 
 Kevin

How about we discuss our usecase first, then we could work on the API for declaration, use, print and foreach. Given our initial work as a basis, the implementation then should be easy either using templates or compile-time functions (I've seen your implementation and I must admit that I'm a bit disappointed that it doesn't look that much better than the one which used templates). I'll open a new thread so that the discussion about the design is seen by everyone, hopefully some will contribute. renoX

Okay. A lot of the awkwardness in the code for the second one is due to limitations in the current CTFE. Things like char[][], functions like split(), format(), replace(), and so on from std.strings, would have made the code much simpler. I think in all these cases it is a matter of time. It's quite amazing that the CTFE stuff was added to DMD as quickly as it was but it has a few limits yet and its amazing how much of the language and library even a simple case like this uses. Kevin
Feb 19 2007