Thread overview
Request: nested enums
Jul 15, 2013
JS
Jul 15, 2013
JS
Jul 16, 2013
Yota
Jul 16, 2013
JS
Jul 16, 2013
JS
July 15, 2013
I think it would be nice to have such a feature:

enum A
{
   a, b, c
   enum B
   {
      d, e, f
   }
}

this helps with logically nested types.

Possibly A.B returns the first(or possibly default) entry of the list(d).

Also, a useful property would be to uniformly distribute the enums inside the int range(or make it optional). This makes changes to an enum less likely to break things such as communications with older apps that use an older version of the enum.

Basically each nested enum occupies a range of 1 to N with N being relatively large but a fraction of int.max.


July 15, 2013
Here is a better example that can actually be implemented but not pretty:



final immutable struct Msg
{
    immutable int Foo = 0;
    immutable int Bar = 1;
    final immutable struct Type
    {
        immutable int Error = 10000;
        immutable int Ok = 10001;
    }
}

Here type is not necessarily a logical subtype of Msg but better stated as Msg.Type.Error rather than MsgType.Error.

If a flag distribution was used, we could do Msg.Foo || Msg.Type.Error.

In any case generating such a structure is a bit of a pain compared to a normal enum.
July 16, 2013
On Monday, 15 July 2013 at 13:47:21 UTC, JS wrote:
> Here is a better example that can actually be implemented but not pretty:
>
>
>
> final immutable struct Msg
> {
>     immutable int Foo = 0;
>     immutable int Bar = 1;
>     final immutable struct Type
>     {
>         immutable int Error = 10000;
>         immutable int Ok = 10001;
>     }
> }
>
> Here type is not necessarily a logical subtype of Msg but better stated as Msg.Type.Error rather than MsgType.Error.
>
> If a flag distribution was used, we could do Msg.Foo || Msg.Type.Error.
>
> In any case generating such a structure is a bit of a pain compared to a normal enum.

That could cause a bit of readability issue.  If you know Msg is
an enum, and then see in the code Msg.Foo, Msg.Bar, and Msg.Type,
any programmer is gonna instantly assume that Msg.Type is just
another value.  If they see Msg.Type.Error, and are still certain
that Msg is an enum, they they might reason that the enum is of a
user defined type, and you're reading the Error field/property.
Either way, it seems a bit counterproductive.

I do see the appeal of nesting types though, as I dislike dumping
things into the global namespace, so I might advise something
like this:

struct Msg {
	enum Type { Foo, Bar }
	enum Result { Error, OK }
}

Be careful with ORing values from different enums though, as the
result type won't be an enum.
July 16, 2013
On Tuesday, 16 July 2013 at 15:50:54 UTC, Yota wrote:
> On Monday, 15 July 2013 at 13:47:21 UTC, JS wrote:
>> Here is a better example that can actually be implemented but not pretty:
>>
>>
>>
>> final immutable struct Msg
>> {
>>    immutable int Foo = 0;
>>    immutable int Bar = 1;
>>    final immutable struct Type
>>    {
>>        immutable int Error = 10000;
>>        immutable int Ok = 10001;
>>    }
>> }
>>
>> Here type is not necessarily a logical subtype of Msg but better stated as Msg.Type.Error rather than MsgType.Error.
>>
>> If a flag distribution was used, we could do Msg.Foo || Msg.Type.Error.
>>
>> In any case generating such a structure is a bit of a pain compared to a normal enum.
>
> That could cause a bit of readability issue.  If you know Msg is
> an enum, and then see in the code Msg.Foo, Msg.Bar, and Msg.Type,
> any programmer is gonna instantly assume that Msg.Type is just
> another value.  If they see Msg.Type.Error, and are still certain
> that Msg is an enum, they they might reason that the enum is of a
> user defined type, and you're reading the Error field/property.
> Either way, it seems a bit counterproductive.
>

I can't do anything about invalid assumptions people make. Alias has the exact same issue you state. If the programmer doesn't want to take the time to look at the code properly then it's their fault.

If one wants to avoid
> I do see the appeal of nesting types though, as I dislike dumping
> things into the global namespace, so I might advise something
> like this:
>
> struct Msg {
> 	enum Type { Foo, Bar }
> 	enum Result { Error, OK }
> }
>
> Be careful with ORing values from different enums though, as the
> result type won't be an enum.

July 16, 2013
If one want's to avoid that problem, just don't allow the nested enum also have a value. It's not a huge deal but just a sort of alias this concept applied to enums:

enum A { default, a, b, c; alias a this; }