April 11, 2014
On 4/10/2014 7:03 AM, Chad Joan wrote:
> It should be possible, because the argument's context is of the (hypothetical)
> FileAccess enum type.  It should be unambiguous that I intend to use
> FileAccess's "READ" symbol there, and not some other symbol from module scope.

Andrei had actually proposed this years ago.

I talked him out of it on the grounds that it would interact confusingly with overloading.
April 11, 2014
On 4/9/2014 9:16 PM, Mike wrote:
> Perhaps using enum for bit flags is fundamentally incorrect and only done
> because there is no language support for bit flags.  If bit flags were a
> first-class citizen of the language with its own semantics, the proposal
> wouldn't be so restrictive.  Adding some bit flag language support may be one
> way to improve enum and the overall language semantics at the same time.

Bit flag usage is often more complex than just bit flags. Sometimes there are "unions" of different meanings for some bit sequences depending on the state of other bits.

Besides, bit flags aren't the only instance of "an integral type where some values have names". The Color enum is another one.

April 11, 2014
On 4/11/14, deadalnix <deadalnix@gmail.com> wrote:
> We don't need a wrapper, we simply need to stop to port header with what you call C style enum. It is completely useless, and the whole problem you mention come from the fact that the header was translated to that.

Yeah I agree. Other than allowing C code to be more easily ported to D, these C-style enums are really ugly.
April 11, 2014
On Thursday, April 10, 2014 22:40:14 Walter Bright wrote:
> On 4/10/2014 10:29 PM, Jonathan M Davis wrote:
> > If you just want to give a list of values names, then you can use manifest constants rather than an enumeration.
> 
> You could, but then you'd lose the self-documenting aspect of static type checking. See the "Color" example.
> 
>      alias int Color;
> 
> doesn't offer any protection from a Color value getting mixed up with a file mode mask.

Except that the only static type checking you're getting is protection against direct assignment. It's trivial to mutate an existing Color to a value not enumerated in Color. Also, what's the point of protecting the type if the intention is that the enumeration only lists _some_ of the values? If it's only listing some of the values, then it's expected that other values could and will be used, so the protection against assigning other values to Color would in fact be counterproductive.

And if an enumeration _is_ listing all of the values, then why not fully protect the enum type and make it illegal to do any operation on it (other than a cast) which makes it be a value other than one of the enumerated values?

Really, as it stands, enum types provides next to no protection against having variables of that type be values other than the enumerated ones

Either enumerations only list some of the expected values, in which case, the protection against assignment of other values is a hindrance when unlisted values are used, or enumerations list all of the values, in which case, protecting only direct assignment isn't enough.

- Jonathan M Davis
April 11, 2014
On 11/04/14 07:40, Walter Bright wrote:

> You could, but then you'd lose the self-documenting aspect of static
> type checking. See the "Color" example.
>
>      alias int Color;
>
> doesn't offer any protection from a Color value getting mixed up with a
> file mode mask.

Then you might want to use a struct instead.

-- 
/Jacob Carlborg
April 11, 2014
On 4/10/2014 11:33 PM, Jacob Carlborg wrote:
> Then you might want to use a struct instead.

I have said the same about the use case of an enum that only consists of its named values.

April 11, 2014
On 4/10/2014 11:25 PM, Jonathan M Davis wrote:
> Except that the only static type checking you're getting is protection against
> direct assignment.

More than that. It's arguments to functions, and overloading.

April 11, 2014
On 4/11/2014 12:03 AM, Walter Bright wrote:
> On 4/10/2014 11:33 PM, Jacob Carlborg wrote:
>> Then you might want to use a struct instead.
>
> I have said the same about the use case of an enum that only consists of its
> named values.


The point being that D is powerful enough that you can use structs and templates to create all kinds of types with custom behaviors. They don't all need to be baked into the core language.
April 11, 2014
On Friday, April 11, 2014 00:05:21 Walter Bright wrote:
> On 4/10/2014 11:25 PM, Jonathan M Davis wrote:
> > Except that the only static type checking you're getting is protection against direct assignment.
> 
> More than that. It's arguments to functions, and overloading.

Well, arguments to functions are essentially the same as direct assignment in the sense that the compiler is protecting against you explicitly giving a variable of an enum type a value that isn't one of its enumerated values, but I did definitely forget about overloading. Still, if the idea is that enums list only some of their possible values, what does overloading really buy you? Again, you have the problem that you have schizoid situation where the compiler is trying to treat the enum differently from its base type and yet its enumerated values are only supposed to be _some_ of its possible values, meaning that its other possible values require casts - and even worse, they require casts just for a few specific operations.

The protections against setting an enum variable to a non-enumerated value would seem to indicate that enum variables should only have one of the values which was explicitly enumerated by that enum type. Certainly, I don't see much point in having those protections if it's expected that an enum variable can have other values. The protections just make it harder to use those other values.

And if we're going to protect against setting a variable of an enum type to a non-enumerated value (be it via direct assignment or via a function argument), why not protect against _all_ operations which would result in an enum variable having a value which wasn't enumerated? What's so special about directly setting the variable versus other operations (e.g. arithmetic or concatenation)?

Also, both language features (e.g. final switch) and the standard library (e.g. std.conv.to) expect for a variable of an enum type to only have one of the enumerated values. So, code which uses other values for enums is likely to have serious problems.

And honestly, I don't see much point to enums if they're not intended to list all of their values. And I'm quite certain that the vast majority of D code using enums assumes that an enum variable is one of the enumerated values. It may very well be the case that there's D code out there that doesn't have that expectation, but Phobos does, and every discussion I've ever seen on it seems to. Your post suggesting that it's not necessarily intended that an enum variable only hold one of the enumerated values is the first time that I've ever seen anyone suggest that, and given how final switch works and the few protections we do have against giving an enum variable non-enumerated values, it certainly seems like the language is designed with the idea that all of the possible values of an enum be enumerated rather than expect that there could be others.

- Jonathan M Davis
April 11, 2014
On Friday, 11 April 2014 at 11:18:34 UTC, Jonathan M Davis wrote:
> On Friday, April 11, 2014 00:05:21 Walter Bright wrote:
>> On 4/10/2014 11:25 PM, Jonathan M Davis wrote:
>> > Except that the only static type checking you're getting is protection
>> > against direct assignment.
>> 
>> More than that. It's arguments to functions, and overloading.
>
> Well, arguments to functions are essentially the same as direct assignment in
> the sense that the compiler is protecting against you explicitly giving a
> variable of an enum type a value that isn't one of its enumerated values, but
> I did definitely forget about overloading. Still, if the idea is that enums
> list only some of their possible values, what does overloading really buy you?
> Again, you have the problem that you have schizoid situation where the
> compiler is trying to treat the enum differently from its base type and yet
> its enumerated values are only supposed to be _some_ of its possible values,
> meaning that its other possible values require casts - and even worse, they
> require casts just for a few specific operations.
>
> The protections against setting an enum variable to a non-enumerated value
> would seem to indicate that enum variables should only have one of the values
> which was explicitly enumerated by that enum type. Certainly, I don't see much
> point in having those protections if it's expected that an enum variable can
> have other values. The protections just make it harder to use those other
> values.
>
> And if we're going to protect against setting a variable of an enum type to a
> non-enumerated value (be it via direct assignment or via a function argument),
> why not protect against _all_ operations which would result in an enum
> variable having a value which wasn't enumerated? What's so special about
> directly setting the variable versus other operations (e.g. arithmetic or
> concatenation)?
>
> Also, both language features (e.g. final switch) and the standard library
> (e.g. std.conv.to) expect for a variable of an enum type to only have one of
> the enumerated values. So, code which uses other values for enums is likely to
> have serious problems.
>
> And honestly, I don't see much point to enums if they're not intended to list
> all of their values. And I'm quite certain that the vast majority of D code
> using enums assumes that an enum variable is one of the enumerated values. It
> may very well be the case that there's D code out there that doesn't have that
> expectation, but Phobos does, and every discussion I've ever seen on it seems
> to. Your post suggesting that it's not necessarily intended that an enum
> variable only hold one of the enumerated values is the first time that I've
> ever seen anyone suggest that, and given how final switch works and the few
> protections we do have against giving an enum variable non-enumerated values,
> it certainly seems like the language is designed with the idea that all of the
> possible values of an enum be enumerated rather than expect that there could
> be others.
>
> - Jonathan M Davis


I agree with you here.