digitalmars.D - Private enum members
- Justin Johansson (14/14) Oct 23 2009 My google search for
- Justin Johansson (2/5) Oct 23 2009
- Yigal Chripun (6/10) Oct 24 2009 enum Color { RED, GREEN, BLUE }
- Justin Johansson (21/36) Oct 24 2009 Okay; that's one work around for a corner case of my cited use-case, but
- Denis Koroskin (11/57) Oct 24 2009 Another useful use-case I see is enforcing explicit initialization:
- Justin Johansson (5/79) Oct 24 2009 Absolutely!
- Yigal Chripun (14/82) Oct 24 2009 I'd prefer D to have support for:
- Justin Johansson (13/105) Oct 24 2009 Let me try again. You have a set of N things which are represented by
- Michel Fortin (7/15) Oct 24 2009 Sounds like you want enum inheritance: one enum being a superset of
- Denis Koroskin (37/49) Oct 24 2009 It was previously proposed, but it was rejected because it works
- Rainer Deyke (5/11) Oct 24 2009 Just like contravariant functions. Only less so.
- Yigal Chripun (6/17) Oct 24 2009 the idea of enum inheritance crossed my mind too.
- Lars T. Kyllingstad (9/16) Oct 26 2009 I agree that enum is a horrible keyword to use for declaring manifest
- Yigal Chripun (17/33) Oct 26 2009 i don't think we need to add more options, I think we need to remove
- Lars T. Kyllingstad (12/52) Oct 27 2009 I was going to protest: "But what about const struct members? Should the...
- Yigal Chripun (7/25) Oct 27 2009 what D version?
- Lars T. Kyllingstad (8/36) Oct 27 2009 Yes, but in D2 the spec says that const is a constant view of mutable
- Ary Borenszweig (2/8) Oct 24 2009 Thanks, fixed!
- Kagamin (6/10) Oct 26 2009 It's syntactical ambiguity, I think. There's no much difference between
My google search for private "enum member" site:digitalmars.com come up with nothing much so presumably this hasn't been discussed before. There may be a valid use-case for being allowed to selectively mark some enum members as being private, such as enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE } (The above doesn't work in D1. Haven't tried D2 though.) (btw. Interestingly, typing this code into Eclipse with the Descent plug-in causes a Java out of heap space malfunction.) Is this a valid use-case? What do you think? -- Justin Johansson
Oct 23 2009
Sorry; subject line mod'ed just so Ary doesn't miss it.enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descent plug-in causes a Java out of heap space malfunction.)
Oct 23 2009
On 24/10/2009 01:16, Justin Johansson wrote:Sorry; subject line mod'ed just so Ary doesn't miss it.enum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descent plug-in causes a Java out of heap space malfunction.)
Oct 24 2009
Yigal Chripun Wrote:On 24/10/2009 01:16, Justin Johansson wrote:Okay; that's one work around for a corner case of my cited use-case, but you don't always want to, or perhaps it is not convenient/elegant to, use a pointer to data that conveniently fits into a machine register. Perhaps I am wrong but I thought uninit was a good metaphor to demonstrate the various useful purposes that private enum members might have. Here is another example that might make the concept jell. Again I may well be wrong. Consider this hypothetical enum definition together with plausible comments: enum Color { RED, GREEN, BLUE, // these 3 members are available for public consumption private RED_WITH_BLUE_POKER_DOTS, // this value is used internally and is not for public consumption and that's why it is marked private private RED_OR_GREEN, // ditto; internal routine to cater for red-green color-blindness } The above demonstrates a set of entities that are meaningful to some possible internal function but otherwise not externally meaningful. Another use-case lies in the API programmer's want for "private" .. so, for example, consider that "private" may well be a synonym for "pleasedontusethismemberbecauseitisalikelycandidateforfuturedeprecation" ** ** Using Walter Bright insignificant whitespace/separator notation :-) Thanks Yigal for commenting and perhaps your further comment? JustinSorry; subject line mod'ed just so Ary doesn't miss it.enum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descent plug-in causes a Java out of heap space malfunction.)
Oct 24 2009
On Sat, 24 Oct 2009 19:00:10 +0400, Justin Johansson <no spam.com> wrote:Yigal Chripun Wrote:Another useful use-case I see is enforcing explicit initialization: enum Color { private Uninitialized = 0, Red, Green, Blue, } Color color; // error: Color.Uninitialized is not accessible It would work similar to private struct ctors.On 24/10/2009 01:16, Justin Johansson wrote:Okay; that's one work around for a corner case of my cited use-case, but you don't always want to, or perhaps it is not convenient/elegant to, use a pointer to data that conveniently fits into a machine register. Perhaps I am wrong but I thought uninit was a good metaphor to demonstrate the various useful purposes that private enum members might have. Here is another example that might make the concept jell. Again I may well be wrong. Consider this hypothetical enum definition together with plausible comments: enum Color { RED, GREEN, BLUE, // these 3 members are available for public consumption private RED_WITH_BLUE_POKER_DOTS, // this value is used internally and is not for public consumption and that's why it is marked private private RED_OR_GREEN, // ditto; internal routine to cater for red-green color-blindness } The above demonstrates a set of entities that are meaningful to some possible internal function but otherwise not externally meaningful. Another use-case lies in the API programmer's want for "private" .. so, for example, consider that "private" may well be a synonym for "pleasedontusethismemberbecauseitisalikelycandidateforfuturedeprecation" ** ** Using Walter Bright insignificant whitespace/separator notation :-) Thanks Yigal for commenting and perhaps your further comment? JustinSorry; subject line mod'ed just so Ary doesn't miss it.plug-inenum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descentenum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?causes a Java out of heap space malfunction.)
Oct 24 2009
Denis Koroskin Wrote:On Sat, 24 Oct 2009 19:00:10 +0400, Justin Johansson <no spam.com> wrote:Absolutely! In general, I cannot see any reason why protection modifiers should not allowable for enums members in the same manner as for members of structs, classes, et. al.Yigal Chripun Wrote:Another useful use-case I see is enforcing explicit initialization: enum Color { private Uninitialized = 0, Red, Green, Blue, } Color color; // error: Color.Uninitialized is not accessible It would work similar to private struct ctors.On 24/10/2009 01:16, Justin Johansson wrote:Okay; that's one work around for a corner case of my cited use-case, but you don't always want to, or perhaps it is not convenient/elegant to, use a pointer to data that conveniently fits into a machine register. Perhaps I am wrong but I thought uninit was a good metaphor to demonstrate the various useful purposes that private enum members might have. Here is another example that might make the concept jell. Again I may well be wrong. Consider this hypothetical enum definition together with plausible comments: enum Color { RED, GREEN, BLUE, // these 3 members are available for public consumption private RED_WITH_BLUE_POKER_DOTS, // this value is used internally and is not for public consumption and that's why it is marked private private RED_OR_GREEN, // ditto; internal routine to cater for red-green color-blindness } The above demonstrates a set of entities that are meaningful to some possible internal function but otherwise not externally meaningful. Another use-case lies in the API programmer's want for "private" .. so, for example, consider that "private" may well be a synonym for "pleasedontusethismemberbecauseitisalikelycandidateforfuturedeprecation" ** ** Using Walter Bright insignificant whitespace/separator notation :-) Thanks Yigal for commenting and perhaps your further comment? JustinSorry; subject line mod'ed just so Ary doesn't miss it.plug-inenum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descentenum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?causes a Java out of heap space malfunction.)
Oct 24 2009
On 24/10/2009 17:10, Denis Koroskin wrote:On Sat, 24 Oct 2009 19:00:10 +0400, Justin Johansson <no spam.com> wrote:I'd prefer D to have support for: enum Color { Red, Green, Blue } Color color; // compile time error Color? color; // OK I don't understand why would you want to hide certain enum values. In the colors example above, what's the rational behind hiding the RED_OR_GREEN value? personally I'd like to see D enums replaced by Java style enums which make more sense to me. D enums are even worse than C enums since you can write: enum foo = "text"; which to me looks very similar to: auto cat = new Dog;Yigal Chripun Wrote:Another useful use-case I see is enforcing explicit initialization: enum Color { private Uninitialized = 0, Red, Green, Blue, } Color color; // error: Color.Uninitialized is not accessible It would work similar to private struct ctors.On 24/10/2009 01:16, Justin Johansson wrote:Okay; that's one work around for a corner case of my cited use-case, but you don't always want to, or perhaps it is not convenient/elegant to, use a pointer to data that conveniently fits into a machine register. Perhaps I am wrong but I thought uninit was a good metaphor to demonstrate the various useful purposes that private enum members might have. Here is another example that might make the concept jell. Again I may well be wrong. Consider this hypothetical enum definition together with plausible comments: enum Color { RED, GREEN, BLUE, // these 3 members are available for public consumption private RED_WITH_BLUE_POKER_DOTS, // this value is used internally and is not for public consumption and that's why it is marked private private RED_OR_GREEN, // ditto; internal routine to cater for red-green color-blindness } The above demonstrates a set of entities that are meaningful to some possible internal function but otherwise not externally meaningful. Another use-case lies in the API programmer's want for "private" .. so, for example, consider that "private" may well be a synonym for "pleasedontusethismemberbecauseitisalikelycandidateforfuturedeprecation" ** ** Using Walter Bright insignificant whitespace/separator notation :-) Thanks Yigal for commenting and perhaps your further comment? JustinSorry; subject line mod'ed just so Ary doesn't miss it.Descent plug-inenum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with theenum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?causes a Java out of heap space malfunction.)
Oct 24 2009
Yigal Chripun Wrote:On 24/10/2009 17:10, Denis Koroskin wrote:On Sat, 24 Oct 2009 19:00:10 +0400, Justin Johansson <no spam.com> wrote:I'd prefer D to have support for: enum Color { Red, Green, Blue } Color color; // compile time error Color? color; // OKYigal Chripun Wrote:Another useful use-case I see is enforcing explicit initialization: enum Color { private Uninitialized = 0, Red, Green, Blue, } Color color; // error: Color.Uninitialized is not accessible It would work similar to private struct ctors.On 24/10/2009 01:16, Justin Johansson wrote:Okay; that's one work around for a corner case of my cited use-case, but you don't always want to, or perhaps it is not convenient/elegant to, use a pointer to data that conveniently fits into a machine register. Perhaps I am wrong but I thought uninit was a good metaphor to demonstrate the various useful purposes that private enum members might have. Here is another example that might make the concept jell. Again I may well be wrong. Consider this hypothetical enum definition together with plausible comments: enum Color { RED, GREEN, BLUE, // these 3 members are available for public consumption private RED_WITH_BLUE_POKER_DOTS, // this value is used internally and is not for public consumption and that's why it is marked private private RED_OR_GREEN, // ditto; internal routine to cater for red-green color-blindness } The above demonstrates a set of entities that are meaningful to some possible internal function but otherwise not externally meaningful. Another use-case lies in the API programmer's want for "private" .. so, for example, consider that "private" may well be a synonym for "pleasedontusethismemberbecauseitisalikelycandidateforfuturedeprecation" ** ** Using Walter Bright insignificant whitespace/separator notation :-) Thanks Yigal for commenting and perhaps your further comment? JustinSorry; subject line mod'ed just so Ary doesn't miss it.Descent plug-inenum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with theenum Color { RED, GREEN, BLUE } void foo(Color* c) { if (c !is null) handleColor(*c); } what's the need for that UNINITIIALIZED member?causes a Java out of heap space malfunction.)I don't understand why would you want to hide certain enum values. In the colors example above, what's the rational behind hiding the RED_OR_GREEN value?Let me try again. You have a set of N things which are represented by an enum definition. There is some subset of this set containing M things (so M < N) which represents the things meaningful in a public sense. The remaining Q=N-M members of the whole set are only meaningful to some internal processing so this subset containing Q members are designated private. I'm trying to think about this problem in an abstract way; sometimes giving concrete examples like Color colors (pun intended) the abstract problem. Maybe there is no good physical example and therefore I am wrong.personally I'd like to see D enums replaced by Java style enums which make more sense to me. D enums are even worse than C enums since you can write: enum foo = "text"; which to me looks very similar to: auto cat = new Dog;I didn't know this one. It does sound like the design of D enums needs revisiting. Perhaps others will chime in on this?
Oct 24 2009
On 2009-10-24 18:45:10 -0400, Justin Johansson <no spam.com> said:Let me try again. You have a set of N things which are represented by an enum definition. There is some subset of this set containing M things (so M < N) which represents the things meaningful in a public sense. The remaining Q=N-M members of the whole set are only meaningful to some internal processing so this subset containing Q members are designated private. I'm trying to think about this problem in an abstract way; sometimes giving concrete examples like Color colors (pun intended) the abstract problem.Sounds like you want enum inheritance: one enum being a superset of another. :-) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Oct 24 2009
On Sun, 25 Oct 2009 02:22:51 +0300, Michel Fortin <michel.fortin michelf.com> wrote:On 2009-10-24 18:45:10 -0400, Justin Johansson <no spam.com> said:It was previously proposed, but it was rejected because it works "backwards": downcasting is allowed while upcasting is prohibited. Consider the following example (taken from DMD): enum Token { colon, semicolon, eof, // ... max, } enum AsmToken : Token // "extend" an existing enum { dword, // = Token.max + 1 implicitly even, far, naked, near, ptr, qword, seg, word, } Now this is very useful, and less error prone than manual enum values management. Less jump to the usage: AsmToken tok1 = Token.colon; // fine Token tok2 = AsmToken.dword; // error The two lines above are exact opposite of class/interface inheritance behavior: class Token {} class AsmToken : Token {} AsmToken tok1 = new Token(); // error Token tok2 = new AsmToken(); // fine which makes sense but confusing for novices. IIRC, Walter rejected the feature for exactly this reason.Let me try again. You have a set of N things which are represented by an enum definition. There is some subset of this set containing M things (so M < N) which represents the things meaningful in a public sense. The remaining Q=N-M members of the whole set are only meaningful to some internal processing so this subset containing Q members are designated private. I'm trying to think about this problem in an abstract way; sometimes giving concrete examples like Color colors (pun intended) the abstract problem.Sounds like you want enum inheritance: one enum being a superset of another. :-)
Oct 24 2009
Denis Koroskin wrote:On Sun, 25 Oct 2009 02:22:51 +0300, Michel Fortin <michel.fortin michelf.com> wrote:I was about to post the same thing.Sounds like you want enum inheritance: one enum being a superset of another. :-)It was previously proposed, but it was rejected because it works "backwards": downcasting is allowed while upcasting is prohibited.Just like contravariant functions. Only less so. -- Rainer Deyke - rainerd eldwood.com
Oct 24 2009
On 25/10/2009 01:22, Michel Fortin wrote:On 2009-10-24 18:45:10 -0400, Justin Johansson <no spam.com> said:the idea of enum inheritance crossed my mind too. I think the simplest way to do what you want is to have two enums, maybe one with the public members and one with the private ones. another option, a private enum with all the values and a public one with just the public ones.Let me try again. You have a set of N things which are represented by an enum definition. There is some subset of this set containing M things (so M < N) which represents the things meaningful in a public sense. The remaining Q=N-M members of the whole set are only meaningful to some internal processing so this subset containing Q members are designated private. I'm trying to think about this problem in an abstract way; sometimes giving concrete examples like Color colors (pun intended) the abstract problem.Sounds like you want enum inheritance: one enum being a superset of another. :-)
Oct 24 2009
Yigal Chripun wrote:personally I'd like to see D enums replaced by Java style enums which make more sense to me. D enums are even worse than C enums since you can write: enum foo = "text"; which to me looks very similar to: auto cat = new Dog;I agree that enum is a horrible keyword to use for declaring manifest constants. In my opinion the D developers are sometimes a bit too afraid of introducing new keywords, and this is one of the consequences. Personally, I think this would be a better scheme: const: manifest constants, no storage (like const in D1, enum in D2) readonly: used for a read-only view of mutable data (like const in D2) immutable: truly immutable data (like now) -Lars
Oct 26 2009
On 26/10/2009 12:07, Lars T. Kyllingstad wrote:Yigal Chripun wrote:i don't think we need to add more options, I think we need to remove options. there should be only two types, const and mutable. manifest constants should be a linker optimization and immutable is only relevant as part of a concurrency model and even then there's no need for a separate keyword. immutable objects are shared objects where only the owner is allowed to modify it and only if it's done in a thread-safe way (synchronized with locks, lock-free algorithms). void foo() { // can be optimized away (transformed into a manifest constant) // taking address of var is illegal const var = 42; // allocated on the heap and you can pass it's address around auto bar = new const int(42); }personally I'd like to see D enums replaced by Java style enums which make more sense to me. D enums are even worse than C enums since you can write: enum foo = "text"; which to me looks very similar to: auto cat = new Dog;I agree that enum is a horrible keyword to use for declaring manifest constants. In my opinion the D developers are sometimes a bit too afraid of introducing new keywords, and this is one of the consequences. Personally, I think this would be a better scheme: const: manifest constants, no storage (like const in D1, enum in D2) readonly: used for a read-only view of mutable data (like const in D2) immutable: truly immutable data (like now) -Lars
Oct 26 2009
Yigal Chripun wrote:On 26/10/2009 12:07, Lars T. Kyllingstad wrote:I was going to protest: "But what about const struct members? Should the size of the following struct depend on whether the compiler determines it can optimize by turning its const member into a manifest constant?" struct Foo { const int bar = 123; } But then I decided to actually try it with the current DMD2, and found that the compiler does just that! writeln(Foo.sizeof); // Prints "1", not "4" Foo foo; auto p = &foo.bar; // Error: constant 123 is not an lvalue What's going on? Is this intended behaviour? -LarsYigal Chripun wrote:i don't think we need to add more options, I think we need to remove options. there should be only two types, const and mutable. manifest constants should be a linker optimization and immutable is only relevant as part of a concurrency model and even then there's no need for a separate keyword. immutable objects are shared objects where only the owner is allowed to modify it and only if it's done in a thread-safe way (synchronized with locks, lock-free algorithms). void foo() { // can be optimized away (transformed into a manifest constant) // taking address of var is illegal const var = 42; // allocated on the heap and you can pass it's address around auto bar = new const int(42); }personally I'd like to see D enums replaced by Java style enums which make more sense to me. D enums are even worse than C enums since you can write: enum foo = "text"; which to me looks very similar to: auto cat = new Dog;I agree that enum is a horrible keyword to use for declaring manifest constants. In my opinion the D developers are sometimes a bit too afraid of introducing new keywords, and this is one of the consequences. Personally, I think this would be a better scheme: const: manifest constants, no storage (like const in D1, enum in D2) readonly: used for a read-only view of mutable data (like const in D2) immutable: truly immutable data (like now) -Lars
Oct 27 2009
Lars T. Kyllingstad Wrote:I was going to protest: "But what about const struct members? Should the size of the following struct depend on whether the compiler determines it can optimize by turning its const member into a manifest constant?" struct Foo { const int bar = 123; } But then I decided to actually try it with the current DMD2, and found that the compiler does just that! writeln(Foo.sizeof); // Prints "1", not "4" Foo foo; auto p = &foo.bar; // Error: constant 123 is not an lvalue What's going on? Is this intended behaviour? -Larswhat D version? in D1 const is a manifest constant as far as I know. to answer to general question, "what about structs": I'd say that the same rules should apply just like inside functions. struct Foo { const int num = 42; } // num should be a manifest const can you give a use-case/example where you wouldn't want to do that but rather store the constant in the struct?
Oct 27 2009
Yigal Chripun wrote:Lars T. Kyllingstad Wrote:DMD 2.035.I was going to protest: "But what about const struct members? Should the size of the following struct depend on whether the compiler determines it can optimize by turning its const member into a manifest constant?" struct Foo { const int bar = 123; } But then I decided to actually try it with the current DMD2, and found that the compiler does just that! writeln(Foo.sizeof); // Prints "1", not "4" Foo foo; auto p = &foo.bar; // Error: constant 123 is not an lvalue What's going on? Is this intended behaviour? -Larswhat D version?in D1 const is a manifest constant as far as I know.Yes, but in D2 the spec says that const is a constant view of mutable data. There isn't (or at least I can't find) mention that struct members are excepted from this rule.to answer to general question, "what about structs": I'd say that the same rules should apply just like inside functions. struct Foo { const int num = 42; } // num should be a manifest const can you give a use-case/example where you wouldn't want to do that but rather store the constant in the struct?In any case where a different view of the same data is non-const. Or would you also disallow casting away const-ness? -Lars
Oct 27 2009
Justin Johansson wrote:Sorry; subject line mod'ed just so Ary doesn't miss it.Thanks, fixed!enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }(btw. Interestingly, typing this code into Eclipse with the Descent plug-in causes a Java out of heap space malfunction.)
Oct 24 2009
Justin Johansson Wrote:enum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }It's syntactical ambiguity, I think. There's no much difference between private UNINITIALIZED = -1, RED, GREEN, BLUE and private UNINITIALIZED = -1, RED, GREEN, BLUE
Oct 26 2009
Kagamin Wrote:Justin Johansson Wrote:So let's fix it: enum C { private: UNINITIALIZED = -1; public: RED, GREEN, BLUE; } But even now it's easy to set illegal values in client code: C c = RED; c--; // bang! Gotta love the implicit conversions - this is almost like pointer arithmeticsenum Color { private UNINITIALIZED = -1, RED, GREEN, BLUE }It's syntactical ambiguity, I think. There's no much difference between private UNINITIALIZED = -1, RED, GREEN, BLUE and private UNINITIALIZED = -1, RED, GREEN, BLUE
Oct 26 2009
d-noob Wrote:So let's fix it: enum C { private: UNINITIALIZED = -1; public: RED, GREEN, BLUE; }See enums with virtual methods http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Oct 26 2009