On Tue, 08 Apr 2014 15:08:46 -0400, Andrei Alexandrescu
<[email protected]> wrote:
(moving http://goo.gl/ZISWwN to this group)
On 4/7/14, 3:41 PM, w0rp wrote:
Yeah, I've seen this happen before. I think we could actually introduce
a little more type safety on enums without a great deal of breakage. It
would be nice to have a final switch give you as much of a guarantee
about what it's doing as it can.
People use enums for things such as:
1. A discrete set of categorical values:
enum State { initial, waiting, running, done }
That's probably the most common use, and the one that prompted the
moniker "enum(eration)".
On these, virtually no arithmetic makes any sense. At most, some notion
of State successor(State) and State predecessor(State) may be sensible.
It would return the next/previously naturally occurring discrete value,
and would either throw, assert, or saturate at limits.
I don't think this is necessarily true. Any kind of assumed order may be
incorrect.
2. A collection of power-of-two flags that can be combined with "or" and
picked apart with "and".
enum AccountFlags { active = 1, overdrawn, hasDiscount = 4, primary = 8 }
That overdrawn without a specific value!!! Please, nobody do that :)
3. A discrete set of categorical values, not all of which are named:
enum UserID : ulong { nobody, expired = ulong.max }
There would be no arithmetic/logic for such enums - they are only to
express categories. Comparisons for equality are needed; comparisons for
inequality may or may not be needed.
4. A "clone" of a type (usually numeric) that's generally used as a
helper for better typing.
enum Kilogram : double {}
enum Percent {}
All usual arithmetic is supposed to work. The enum acts as a subtype of
its base type.
I haven't seen that use in a while. Is that something we want to promote?
The current design is loose enough to accommodate all of the above uses,
probably too loose because it allows a bunch of nonsensical code to
compile. There are several questions to ask ourselves:
1. Is the current design damaging enough (= allows enough wrong/buggy
code to pass through) to warrant a breaking tightening?
2. To what extent can library-based approaches help?
3. What is the priority of improving enums in the larger picture of
other things we must do?
What about allowing enum methods? e.g.:
enum State
{
initial, waiting, running, done;
State next() { if(this == done) return done; return State(cast(int)this
+ 1);}
}
I'm not sure what benefits this has over just defining a struct instead.
In fact, an enum-as-a-type is essentially an easy-to-define wrapper struct.
Not sure if it's relevant to this discussion, but there are also anonymous
enums.
-Steve