www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - enum value vs. immutable

reply "CJS" <Prometheus85 hotmail.com> writes:
I was reading the enum page of Ali Çehreli's (excellent) D book 
(http://ddili.org/ders/d.en/enum.html), and I'm confused by an 
enum value (not enum type), such as
    enum secondsPerDay = 60 * 60 * 24;
In that situation I would have used an immutable variable. Is 
there any reason to prefer enum vs. immutable when defining 
constants?
Dec 01 2013
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/01/2013 09:57 PM, CJS wrote:

 I was reading the enum page of Ali Çehreli's (excellent) D book
 (http://ddili.org/ders/d.en/enum.html), and I'm confused by an enum
 value (not enum type), such as
     enum secondsPerDay = 60 * 60 * 24;
 In that situation I would have used an immutable variable. Is there any
 reason to prefer enum vs. immutable when defining constants?
After realizing the other day that even 'static const' can be used for template instantiations, I am not sure myself anymore. :) Simple rules are great. I wanted to accept the following guidelines, none of which are clear cut: 1) Prefer enum first because enum values can be used for template instantiations. 2) Prefer immutable next because it provides stronger guarantees. 3) Prefer const last as it erases immutable attribute if present. (We can't know just by looking at a reference to const whether the original value has been immutable or mutable.) The first item needs qualification: Do not use enum for arrays and associative arrays, because enum is like copy+pasting the definition everywhere the enum is used. It is expensive to initialize arrays and AAs. The second item needs qualification: immutable is not just a stronger const, it is a requirement, a burden. It requires that the object is deeply immutable and it is also a burden on types: They cannot contain mutable references. (This affects future development; you can't add mutable references to a type that has already been used as immutable somewhere in the code.) So, it is not a clear cut decision because it depends on the type as well. For example, these days I use const even for manifest constants like 60 * 60 * 24 because for all practical purposes it is a manifest constant! This must be new in D; I don't think it worked that way but it works even with CTFE now. Additionally const is shorter to type and easier on the eyes. :) Ali
Dec 01 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Monday, 2 December 2013 at 07:27:25 UTC, Ali Çehreli wrote:
 On 12/01/2013 09:57 PM, CJS wrote:

 I was reading the enum page of Ali Çehreli's (excellent) D
book
 (http://ddili.org/ders/d.en/enum.html), and I'm confused by
an enum
 value (not enum type), such as
     enum secondsPerDay = 60 * 60 * 24;
 In that situation I would have used an immutable variable. Is
there any
 reason to prefer enum vs. immutable when defining constants?
After realizing the other day that even 'static const' can be used for template instantiations, I am not sure myself anymore. :) Simple rules are great. I wanted to accept the following guidelines, none of which are clear cut: 1) Prefer enum first because enum values can be used for template instantiations.
You can instatiate templates not only with enums. Main pro for enums is that they are CT values.
 3) Prefer const last as it erases immutable attribute if 
 present. (We can't know just by looking at a reference to const 
 whether the original value has been immutable or mutable.)
It is interesting to know where such advices come from. Const in D is useless except as as parameter qualifier, method qualifier, tool to alias const data and non-const data and as qualifier of some field - member of aggregate. Writing code like const int i = SOME_VALUE; is loosing advantages of immutable or enum while gaining nothing in return. It is C++ism like follwoing code: struct S { public: this(type){} ... } or static Type t; // in module scope
Dec 01 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/01/2013 11:48 PM, Maxim Fomin wrote:

 1) Prefer enum first because enum values can be used for template
 instantiations.
You can instatiate templates not only with enums. Main pro for enums is that they are CT values.
The confusion is, some const values are CT values as well.
 3) Prefer const last as it erases immutable attribute if present. (We
 can't know just by looking at a reference to const whether the
 original value has been immutable or mutable.)
It is interesting to know where such advices come from. Const in D is useless except as as parameter qualifier, method qualifier, tool to alias const data and non-const data and as qualifier of some field - member of aggregate. Writing code like const int i = SOME_VALUE; is loosing advantages of immutable or enum while gaining nothing in
return. That works for some types as both enum and immutable have their problems: * enum is no good for arrays and AAs as it is very likely to be unnecessarily slow. * immutable is no good for types that contain mutable references at least during assignment: struct S { int i; int[] others; } void main() { auto a = S(42); immutable b = a; // Error: cannot implicitly convert expression (a) of type S to immutable(S) }
 It is C++ism like follwoing code:

 struct S { public: this(type){} ... }

 or

 static Type t; // in module scope
Both of those do happen. ;) Ali
Dec 03 2013
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 3 December 2013 at 08:28:23 UTC, Ali Çehreli wrote:
 That works for some types as both enum and immutable have their 
 problems:

 * enum is no good for arrays and AAs as it is very likely to be 
 unnecessarily slow.

 * immutable is no good for types that contain mutable 
 references at least during assignment:

 struct S
 {
     int i;
     int[] others;
 }

 void main()
 {
     auto a = S(42);
     immutable b = a;
 // Error: cannot implicitly convert expression (a) of type S to 
 immutable(S)
 }
Kenji is working on this http://wiki.dlang.org/DIP49
 It is C++ism like follwoing code:

 struct S { public: this(type){} ... }

 or

 static Type t; // in module scope
Both of those do happen. ;) Ali
Yes, this isn't good at all.
Dec 03 2013
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 Do not use enum for arrays and associative arrays, because enum 
 is like copy+pasting the definition everywhere the enum is 
 used. It is expensive to initialize arrays and AAs.
Lot of time ago I think Don suggested to disallow enum dynamic and associave arrays. enum is partially broken, but I am not seeing much effort in trying to fix it. Bye, bearophile
Dec 02 2013
prev sibling next sibling parent reply "Sergei Nosov" <sergei.nosov gmail.com> writes:
On Monday, 2 December 2013 at 05:57:33 UTC, CJS wrote:
 I was reading the enum page of Ali Çehreli's (excellent) D book 
 (http://ddili.org/ders/d.en/enum.html), and I'm confused by an 
 enum value (not enum type), such as
    enum secondsPerDay = 60 * 60 * 24;
 In that situation I would have used an immutable variable. Is 
 there any reason to prefer enum vs. immutable when defining 
 constants?
enum is a compile-time constant and an immutable variable is not. As an example, in order to create a enum variable you have to know it's value at compile time, e.g. you can't read it from file. On the contrary, you can read a string from file and string is the same thing as immutable(char) in D.
Dec 01 2013
parent "Sergei Nosov" <sergei.nosov gmail.com> writes:
On Monday, 2 December 2013 at 07:31:56 UTC, Sergei Nosov wrote:
 On Monday, 2 December 2013 at 05:57:33 UTC, CJS wrote:
 I was reading the enum page of Ali Çehreli's (excellent) D 
 book (http://ddili.org/ders/d.en/enum.html), and I'm confused 
 by an enum value (not enum type), such as
   enum secondsPerDay = 60 * 60 * 24;
 In that situation I would have used an immutable variable. Is 
 there any reason to prefer enum vs. immutable when defining 
 constants?
enum is a compile-time constant and an immutable variable is not. As an example, in order to create a enum variable you have to know it's value at compile time, e.g. you can't read it from file. On the contrary, you can read a string from file and string is the same thing as immutable(char) in D.
Typo - "the string is the same thing as immutable(char)[]" in D (note the rectangular braces)
Dec 01 2013
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, December 02, 2013 06:57:32 CJS wrote:
 I was reading the enum page of Ali Çehreli's (excellent) D book
 (http://ddili.org/ders/d.en/enum.html), and I'm confused by an
 enum value (not enum type), such as
     enum secondsPerDay = 60 * 60 * 24;
 In that situation I would have used an immutable variable. Is
 there any reason to prefer enum vs. immutable when defining
 constants?
enum doesn't create a variable, so if all you really want is for the value to be used and don't care about having an actual variable, there's really no reason to use an immutable variable. Also, enum has the advantage that it _has_ to be known at compile time even if it's a local variable, so its value with be determined at compile time, not runtime, which is almost always an advantage. The main situations where you should prefer an immutable variable are for arrays and AAs or for any type or situation where the value needs to be determined at runtime or where it would be better if it were. The main problem with arrays and AAs and enums, is that you end up allocating a new one every time the enum is used, which won't happen with a variable and isn't a problem for other types of enums (as any other type which would be allocated on the heap can't be an enum). Strings are an exception with regards to arrays as string literals end up in a special place in memory rather than being duplicated, so you don't end up with an allocation every time you use it. Overall though, it's better to use enum for constants. Using a variable just creates extra overhead (minimal though it may be). - Jonathan M Davis
Dec 02 2013