digitalmars.D - Should all enums be immutable?
- Jonathan M Davis (17/17) Apr 04 2011 Enum values cannot be altered. It is an error to try and assign a value ...
- Don (7/25) Apr 04 2011 Yes. The ONLY reason those manifest constants exist at all, is so that
- Rainer Schuetze (4/32) Apr 04 2011 Unfortunately, you currently get the same performance penalty with const...
- Nick Sabalausky (16/48) Apr 05 2011 /me looks through all his D code for any enum/immutable/const arrays...
- Don (5/56) Apr 06 2011 No. It's just a workaround for an optlink bug: manifest constants that
- Trass3r (3/7) Apr 06 2011 Don't you mean immutable in this case?
- Simen kjaeraas (9/13) Apr 06 2011 Yup. In theory, any immutable Foo declared at module scope (and likely
- Trass3r (6/9) Apr 06 2011 Ok, I guess the hack works by replacing every occurrence of the constant...
- Simen kjaeraas (4/14) Apr 07 2011 Correct on both counts.
- Nick Sabalausky (4/36) Apr 05 2011 What about "enum string x = ..." or "immutable string x = ..."? Anyone k...
- Steven Schveighoffer (3/6) Apr 05 2011 No, strings are generated at compile time via a literal or CTFE.
-
Stewart Gordon
(12/15)
Apr 05 2011
- Don (4/24) Apr 06 2011 No. NONE exist at run time. That is the whole point. No enum should ever...
-
Stewart Gordon
(5/7)
Apr 09 2011
- Jonathan M Davis (15/25) Apr 09 2011 Every time that you use an enum, it's replaced with the enum's value. So...
-
Stewart Gordon
(10/15)
Apr 09 2011
-
Stewart Gordon
(6/13)
Apr 05 2011
Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable? - Jonathan M Davis
Apr 04 2011
Jonathan M Davis wrote:Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable?Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug. Almost all existing enum arrays or AAs are bugs. For example, if you have a lookup table which should be used at runtime, it should ALWAYS be defined as const or immutable, not as an enum.
Apr 04 2011
Don wrote:Jonathan M Davis wrote:Unfortunately, you currently get the same performance penalty with const or immutable arrays as with enum: http://d.puremagic.com/issues/show_bug.cgi?id=4298Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable?Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug. Almost all existing enum arrays or AAs are bugs. For example, if you have a lookup table which should be used at runtime, it should ALWAYS be defined as const or immutable, not as an enum.
Apr 04 2011
"Rainer Schuetze" <r.sagitario gmx.de> wrote in message news:ind21j$1si5$1 digitalmars.com...Don wrote:/me looks through all his D code for any enum/immutable/const arrays... Even once it gets fixed for immutable/const, I hope it still gets fixed for enum, too. It'd be a real pain to have to think about "enum or immutable?" every time I need a fixed named value. And I can imagine that also causing problems for metaprogramming: template foo(T, alias val) { // Oops!! Sometimes needs to be immutable! // Gotta split this into two template overloads... enum T foo = val; } My understanding was that the point of enum (the manifest constant enum) was to serve as *the* de facto way to do fixed named values because of a particular limitation of trying to do the same with immutable.Jonathan M Davis wrote:Unfortunately, you currently get the same performance penalty with const or immutable arrays as with enum: http://d.puremagic.com/issues/show_bug.cgi?id=4298Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable?Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug. Almost all existing enum arrays or AAs are bugs. For example, if you have a lookup table which should be used at runtime, it should ALWAYS be defined as const or immutable, not as an enum.
Apr 05 2011
Nick Sabalausky wrote:"Rainer Schuetze" <r.sagitario gmx.de> wrote in message news:ind21j$1si5$1 digitalmars.com...No. It's just a workaround for an optlink bug: manifest constants that are never used, still get put into the executable. By default, you should use const, not enum. You should forget that enum manifest constants even exist.Don wrote:/me looks through all his D code for any enum/immutable/const arrays... Even once it gets fixed for immutable/const, I hope it still gets fixed for enum, too. It'd be a real pain to have to think about "enum or immutable?" every time I need a fixed named value. And I can imagine that also causing problems for metaprogramming: template foo(T, alias val) { // Oops!! Sometimes needs to be immutable! // Gotta split this into two template overloads... enum T foo = val; } My understanding was that the point of enum (the manifest constant enum) was to serve as *the* de facto way to do fixed named values because of a particular limitation of trying to do the same with immutable.Jonathan M Davis wrote:Unfortunately, you currently get the same performance penalty with const or immutable arrays as with enum: http://d.puremagic.com/issues/show_bug.cgi?id=4298Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable?Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug. Almost all existing enum arrays or AAs are bugs. For example, if you have a lookup table which should be used at runtime, it should ALWAYS be defined as const or immutable, not as an enum.
Apr 06 2011
Am 06.04.2011, 17:27 Uhr, schrieb Don <nospam nospam.com>:No. It's just a workaround for an optlink bug: manifest constants that are never used, still get put into the executable.What?By default, you should use const, not enum. You should forget that enum manifest constants even exist.Don't you mean immutable in this case?
Apr 06 2011
On Wed, 06 Apr 2011 18:30:43 +0200, Trass3r <un known.com> wrote:Am 06.04.2011, 17:27 Uhr, schrieb Don <nospam nospam.com>:Yup. In theory, any immutable Foo declared at module scope (and likely also those at static class/struct scope) could be elided by the linker if it not used anywhere, but Optlink does not do that. That means of course, that pointer manipulation to get from one manifest constant to another declared right after is not supported (nor should it be *shudder*). -- SimenNo. It's just a workaround for an optlink bug: manifest constants that are never used, still get put into the executable.What?
Apr 06 2011
Am 06.04.2011, 20:40 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:Yup. In theory, any immutable Foo declared at module scope (and likely also those at static class/struct scope) could be elided by the linker if it not used anywhere, but Optlink does not do that.Ok, I guess the hack works by replacing every occurrence of the constant identifier in the AST with the initializer part of "enum foo = initializer;"? So there would be no reason to keep enum manifest constants if this Optlink bug was fixed?
Apr 06 2011
On Wed, 06 Apr 2011 21:42:35 +0200, Trass3r <un known.com> wrote:Am 06.04.2011, 20:40 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:Correct on both counts. -- SimenYup. In theory, any immutable Foo declared at module scope (and likely also those at static class/struct scope) could be elided by the linker if it not used anywhere, but Optlink does not do that.Ok, I guess the hack works by replacing every occurrence of the constant identifier in the AST with the initializer part of "enum foo = initializer;"? So there would be no reason to keep enum manifest constants if this Optlink bug was fixed?
Apr 07 2011
Am 07.04.2011, 18:03 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:On Wed, 06 Apr 2011 21:42:35 +0200, Trass3r <un known.com> wrote:I'm still confused about this. Don't we need enum to have things like PI not consume memory? Which directly brings me to the following: http://www.digitalmars.com/d/2.0/enum.html states that enum ident = val; is just shorthand for enum {ident = val}. Yet it suggests these are different things by calling only these special cases "manifest constants" and stating that SUCH declarations are not lvalues. Even though normal enums aren't lvalues either: enum {a = 5, b} pragma(msg, &b); Error: constant 6 is not an lvalue And also dmd handles them specially by treating enum as a storage class (STC_manifest) in this case.Am 06.04.2011, 20:40 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:Correct on both counts.Yup. In theory, any immutable Foo declared at module scope (and likely also those at static class/struct scope) could be elided by the linker if it not used anywhere, but Optlink does not do that.Ok, I guess the hack works by replacing every occurrence of the constant identifier in the AST with the initializer part of "enum foo = initializer;"? So there would be no reason to keep enum manifest constants if this Optlink bug was fixed?
Apr 07 2011
Trass3r wrote:Am 07.04.2011, 18:03 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:No, the only thing it does it make it not take up space in the executable if it isn't used. And this is a linker issue.On Wed, 06 Apr 2011 21:42:35 +0200, Trass3r <un known.com> wrote:I'm still confused about this. Don't we need enum to have things like PI not consume memory?Am 06.04.2011, 20:40 Uhr, schrieb Simen kjaeraas <simen.kjaras gmail.com>:Correct on both counts.Yup. In theory, any immutable Foo declared at module scope (and likely also those at static class/struct scope) could be elided by the linker if it not used anywhere, but Optlink does not do that.Ok, I guess the hack works by replacing every occurrence of the constant identifier in the AST with the initializer part of "enum foo = initializer;"? So there would be no reason to keep enum manifest constants if this Optlink bug was fixed?Which directly brings me to the following: http://www.digitalmars.com/d/2.0/enum.html states that enum ident = val; is just shorthand for enum {ident = val}. Yet it suggests these are different things by calling only these special cases "manifest constants" and stating that SUCH declarations are not lvalues. Even though normal enums aren't lvalues either: enum {a = 5, b} pragma(msg, &b); Error: constant 6 is not an lvalue And also dmd handles them specially by treating enum as a storage class (STC_manifest) in this case.The terminology stuff is just because they're not enums. There is nothing about them which would justify them being called an "enumerated type". But that's true of anonymous enums, enum { ident = val } as well.
Apr 08 2011
"Rainer Schuetze" <r.sagitario gmx.de> wrote in message news:ind21j$1si5$1 digitalmars.com...Don wrote:What about "enum string x = ..." or "immutable string x = ..."? Anyone know if those exhibit the same problem?Jonathan M Davis wrote:Unfortunately, you currently get the same performance penalty with const or immutable arrays as with enum: http://d.puremagic.com/issues/show_bug.cgi?id=4298Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too. Given that the value of enum must be known at compile time and given that it cannot be changed, why aren't enums all immutable? What's gained by making so that every reference to an enum is replaced by its value rather than actually referencing an immutable value? In most cases, it could still be replaced by the value (since it's a constant) if that's more efficient. And in the case of reference types, it would actually act like a reference type. So, I ask, should enums just all be made automatically immutable instead of having the current replace when referenced semantics? Is there a good reason _not_ to make all enums immutable?Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug. Almost all existing enum arrays or AAs are bugs. For example, if you have a lookup table which should be used at runtime, it should ALWAYS be defined as const or immutable, not as an enum.
Apr 05 2011
On Tue, 05 Apr 2011 19:53:35 -0400, Nick Sabalausky <a a.a> wrote:What about "enum string x = ..." or "immutable string x = ..."? Anyone know if those exhibit the same problem?No, strings are generated at compile time via a literal or CTFE. -Steve
Apr 05 2011
On 04/04/2011 10:32, Don wrote: <snip>Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug.<snip> Eh what? In the case of simple value-type constants, this makes sense. But when they're reference types, many copies exist at run time, rather than only one. This is certainly not an advantage on any level. A reasonable way of doing it is such that every instance of the same enum value has the same bit pattern. For pure value types (primitive types, static arrays and structs/unions consisting only of pure value types) this is straightforward. If a reference type is involved, put the contents in the static data segment and have the enum value referencing this one instance. I presume this can be done...? Stewart.
Apr 05 2011
Stewart Gordon wrote:On 04/04/2011 10:32, Don wrote: <snip>No. NONE exist at run time. That is the whole point. No enum should ever exist in the compiler. That's the only difference between immutable and enum.Yes. The ONLY reason those manifest constants exist at all, is so that they don't exist at run time. They have no address. Any case where taking a reference to them works, is a compiler bug.<snip> Eh what? In the case of simple value-type constants, this makes sense. But when they're reference types, many copies exist at run time, rather than only one. This is certainly not an advantage on any level.A reasonable way of doing it is such that every instance of the same enum value has the same bit pattern. For pure value types (primitive types, static arrays and structs/unions consisting only of pure value types) this is straightforward. If a reference type is involved, put the contents in the static data segment and have the enum value referencing this one instance. I presume this can be done...? Stewart.
Apr 06 2011
On 06/04/2011 16:24, Don wrote: <snip>No. NONE exist at run time. That is the whole point. No enum should ever exist in the compiler. That's the only difference between immutable and enum.<snip> So how, exactly, does the runtime get at data that doesn't exist? Stewart.
Apr 09 2011
On 06/04/2011 16:24, Don wrote: <snip>Every time that you use an enum, it's replaced with the enum's value. So, it's like you put a literal there which was identtical to the enum's value. So, enum a = [1, 2, 3, 4]; void main() { writeln(a); } would become void main() { writeln([1, 2, 3, 4]); } If a had been an immutable variable, then a would not have been replaced with its value in the writeln call, but rather a would be passed to writeln. - Jonathan M DavisNo. NONE exist at run time. That is the whole point. No enum should ever exist in the compiler. That's the only difference between immutable and enum.<snip> So how, exactly, does the runtime get at data that doesn't exist?
Apr 09 2011
On 09/04/2011 22:58, Jonathan M Davis wrote: <snip><snip> That's what I'd made out people were saying. But Don seemed to be claiming that the [1, 2, 3, 4] doesn't exist at runtime.So how, exactly, does the runtime get at data that doesn't exist?Every time that you use an enum, it's replaced with the enum's value. So, it's like you put a literal there which was identtical to the enum's value. So,If a had been an immutable variable, then a would not have been replaced with its value in the writeln call, but rather a would be passed to writeln.Exactly. What I'm claiming ought to happen is for a to be replaced at compiletime with the (length, address) tuple pointing to [1, 2, 3, 4]. Am I imagining it, or is this basically the way string literals work? Stewart.
Apr 09 2011
On 04/04/2011 10:07, Jonathan M Davis wrote:Enum values cannot be altered. It is an error to try and assign a value to an enum. However, the value of an enum isn't really const or immutable. It's copied every time that the enum is used. This is fine in cases where the enum is a value type, but it's problematic when the enum is a reference type. I believe that the classic example is if you have an AA which is an enum. You copy _the entire_ AA every time it's referenced. But it's not just AA's. Normal arrays have the problem too.<snip> There are a few bug reports about this: http://d.puremagic.com/issues/show_bug.cgi?id=2237 http://d.puremagic.com/issues/show_bug.cgi?id=2331 Stewart.
Apr 05 2011