February 19, 2007
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

February 19, 2007
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?
>>>> 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
> 

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