On Saturday, 12 April 2014 at 13:33:07 UTC, Jonathan M Davis wrote:
On further reflection, I think that having enum and final enum would make sense as long as enum were changed so that it introduced an alias rather than a new type. A new type just doesn't make sense if you're not listing all the values - especially because the few protections that the compiler has against giving an enum a non-enumerated value just get in the way of that use case - whereas if the enum _is_ intended to enumerate all its values, it makes sense that it would introduce a new type that was protected against having it set to
non-enumerated values. So,

enum UserID : ulong { nobody, expired = ulong.max }

would then introduce an alias UserID for ulong as well as namespace the constants nobody and expired, but there would be no new type introduced, so it would not protect against being assigned non-enumerated values, and it would
not affect overloading. It also wouldn't work with final switch.

final enum State { initial, waiting, running, done }

would then be the same as

enum State { initial, waiting, running, done }

is now except that the compiler would actually guarantee that no variable of type State could have a non-enumerated value unless a cast was used (so any operation which wasn't guaranteed to result in an enumerated value would result in a value of the base type rather than the enum type). And of course, it would then work properly with final switch, because it couldn't have a non-
enumerated value unless you forced it with a cast.

With that separation, we can then separate out the enums which are really enumerations and those which are really just a group of related constants. But I think that the key thing is that introducing a new type really doesn't make sense if it's just a group of related constants. Introducing an alias is fine
- but a new type just doesn't make sense IMHO.

For better or worse, if we went this route, we'd end up with something closer to C++11's enums and enum classes, though unlike enum classes, our final enum would implicitly convert to its base type, and operations on it which weren't guaranteed to result in a valid enum value would result in the base type, whereas it's my understanding that you have to overload operators to get any
of that working at all with enum classes.

- Jonathan M Davis

If we were really serious about changing enums, I'd say scrap the whole thing and take a look at how Rust does them, and change the semantics of final switch to allow for pattern matching, while leaving switch around as a legacy C construct and discouraging its use in regular code.

Reply via email to