www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - enum and const or immutable =?UTF-8?B?4oCYdmFyaWFibGXigJk=?= whose

reply Cecil Ward <cecil cecilward.com> writes:
A really stupid question, I fear.

If I have some kind of declaration of some ‘variable’ whose value 
is strictly known at compile time and I do one of the following 
(rough syntax)

either
    enum foo = bar;
or
    const foo = bar;
or
    immutable foo = bar;

then is there any downside to just using enum all the time?

- I don’t need to take the address of foo, in fact want to 
discourage &foo, (as I said, given that I can do so)

Is there any upside either to using enum?

I’m a bit nervous about using immutable having had bad allergic 
reactions when passing immutable ‘variables’ to functions and so 
just tend to use const or enum.
Sep 16 2020
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward wrote:
 then is there any downside to just using enum all the time?
For a non-string array, enum may give runtime allocations that static immutable won't. Generally think of enum as being replaced with the literal representation and array literals actually make a new array. This may or may not matter to you.
Sep 16 2020
parent reply Cecil Ward <cecil cecilward.com> writes:
On Wednesday, 16 September 2020 at 17:19:13 UTC, Adam D. Ruppe 
wrote:
 On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward 
 wrote:
 then is there any downside to just using enum all the time?
For a non-string array, enum may give runtime allocations that static immutable won't. Generally think of enum as being replaced with the literal representation and array literals actually make a new array. This may or may not matter to you.
So can the result of declaring certain things with enum ever have an _address_ then? (According to legit D code that is, never mind the underlying implementation details, which may not be observable) <rant>I actually really hate the way enum was bent out of shape and twisted from its original purpose so that finally we end up with a way of defining only one value, not the whole range of permissible values for a type as in the beginning. I wish there were just a keyword ‘constant’ or something (yes, I know, you could just call that something ‘enum’, or ‘const’)</rant>
Sep 16 2020
parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward
 So can the result of declaring certain things with enum ever 
 have an _address_ then? (According to legit D code that is, 
 never mind the underlying implementation details, which may not 
 be observable)
No. Think of it as a named literal. Given enum x = 10, then int num = x is the same as if you had typed int num = 10. Thats’s why you have be careful with array enums if you care about allocations.
 <rant>I actually really hate the way enum was bent out of shape 
 and twisted from its original purpose so that finally we end up 
 with a way of defining only one value, not the whole range of 
 permissible values for a type as in the beginning.

 I wish there were just a keyword ‘constant’ or something (yes, 
 I know, you could just call that something ‘enum’, or 
 ‘const’)</rant>
enum foo is essentially a shortcut for enum { foo }. It’s neither bent out of shape nor twisted. Consider that C++ added the new keyword constexpr for the same thing. Why pollute the namespace with a new keyword when you already have one that fits?
Sep 16 2020
next sibling parent reply claptrap <clap trap.com> writes:
On Thursday, 17 September 2020 at 01:57:39 UTC, Mike Parker wrote:
 On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward

 enum foo is essentially a shortcut for enum { foo }. It’s 
 neither bent out of shape nor twisted. Consider that C++ added 
 the new keyword constexpr for the same thing. Why pollute the 
 namespace with a new keyword when you already have one that 
 fits?
Seriously how it's implemented is irrelevant. When people use it (for that use case) they arn't thinking ohh right here I want an enum with one member. They are thinking I want a constant expression evaluated at compile time. IE, C++ got something right for once, D let the mechanic name the controls on the dashboard. It's an "implementers name" and it's retarded beyond belief. Seriously look up enumeration in a dictionary and explain how that can be twisted to mean "constant expression" or "evaluated at compile time". Names are important, principle of least astonishment and all that, pretty much everyone coming to D is going be WTF in learning about that. And if you keep overloading existing keywords with more and more meanings the code gets harder and harder to grep at first glance.
Sep 17 2020
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 09:44:20 UTC, claptrap wrote:

 Names are important, principle of least astonishment and all 
 that, pretty much everyone coming to D is going be WTF in 
 learning about that. And if you keep overloading existing 
 keywords with more and more meanings the code gets harder and 
 harder to grep at first glance.
I can attest that in the 17 years I've been hanging around here, the fact that enum is used to indicate a manifest constant has not been a serious source of WTF posts. So I think "pretty much everyone coming to D" have decided it's either perfectly fine or perfectly tolerable. It's the sort of thing that may not be obvious, but once you figure you absorb it and get down to coding. I know some people would prefer it were something else and some don't care. I'm squarely in the camp that thinks it makes perfect sense and it would be silly to create a new keyword for it.
Sep 17 2020
parent jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 17 September 2020 at 10:53:48 UTC, Mike Parker wrote:
 [snip]

 I can attest that in the 17 years I've been hanging around 
 here, the fact that enum is used to indicate a manifest 
 constant has not been a serious source of WTF posts. So I think 
 "pretty much everyone coming to D" have decided it's either 
 perfectly fine or perfectly tolerable. It's the sort of thing 
 that may not be obvious, but once you figure you absorb it and 
 get down to coding. I know some people would prefer it were 
 something else and some don't care. I'm squarely in the camp 
 that thinks it makes perfect sense and it would be silly to 
 create a new keyword for it.
A talk at dconf 2019 provided an alternative approach to using enum for manifest constants: http://dconf.org/2019/talks/marques.html
Sep 17 2020
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 09:44:20 UTC, claptrap wrote:

 Seriously how it's implemented is irrelevant.
And to be clear, my point wasn't about how it's implemented. My point was that: enum { foo = 10; } and enum foo = 10; Are effectively the same thing, whether it's implemented that way or not. So why on earth would a new keyword be necessary?
Sep 17 2020
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 17 September 2020 at 10:56:28 UTC, Mike Parker wrote:
 Are effectively the same thing, whether it's implemented that 
 way or not. So why on earth would a new keyword be necessary?
C++ made enums stricter by "enum class".
Sep 17 2020
prev sibling next sibling parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 17 September 2020 at 10:56:28 UTC, Mike Parker wrote:
 On Thursday, 17 September 2020 at 09:44:20 UTC, claptrap wrote:

 Seriously how it's implemented is irrelevant.
And to be clear, my point wasn't about how it's implemented. My point was that: enum { foo = 10; } and enum foo = 10; Are effectively the same thing, whether it's implemented that way or not. So why on earth would a new keyword be necessary?
I could imagine some new users may think in enum foo = someTemplate!(); someTemplate could evaluate to a list of values like a 'normal' enum. That's just conjecture, though. The one thing I dislike about enum like this is that we have another keyword that's able to handle manifest constants when tickled correctly, and which doesn't evoke the image of an enumerated list of values: import std.meta : Alias; alias foo = Alias!([1,2,3]); alias bar = Alias!9; alias baz = Alias!someFunc; Some of the above may be doable without Alias!(), but not all. I don't know if you remember the discussions when bracketless enums were introduced back in 2007ish, but alias was the prime contender back then, and is slowly gaining the power that was requested at the time (the ability to alias values as above was added fairly recently). To quote Bill Baxter from way back when (https://forum.dlang.org/post/fjdc4c$2gft$1 digitalmars.com):
 Why does:
     final int x = 3;
 make any more intuitive sense than:
     enum int x = 3;
 ?
There are these things called "words". And they have "meanings"... enum: (short for "enumeration", the noun form of "enumerate") "to specify one after another : list" final: "not to be altered or undone <all sales are final>"
To be clear: I don't mind 'enum' being used this way, but if I were to do things over again, I would have used 'alias'. -- Simen
Sep 17 2020
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 13:13:46 UTC, Simen Kjærås 
wrote:

 To quote Bill Baxter from way back when
 (https://forum.dlang.org/post/fjdc4c$2gft$1 digitalmars.com):

 Why does:
     final int x = 3;
 make any more intuitive sense than:
     enum int x = 3;
 ?
There are these things called "words". And they have "meanings"... enum: (short for "enumeration", the noun form of "enumerate") "to specify one after another : list" final: "not to be altered or undone <all sales are final>"
To be clear: I don't mind 'enum' being used this way, but if I were to do things over again, I would have used 'alias'.
Well, I was already using anonymous enums for compile-time constants anyway. For example, when translating C headers with lots of #defined constants (OpenGL is the poster child), I was doing this in Derelict: enum { GL_THIS = ..., GL_THAT = ..., } So enum for this has always made sense to me. I would have been fine with final, but it would have been a leap for me because of my Java background; I would have kept seeing it as a synonym for const. And I would never have liked the Alias approach. But no matter what solution would have been implemented (final, Alias, new keyword), I would have looked it up then, put my head down and gotten right back to writing code. It just happens the one that's most intuitive to me was picked :-)
Sep 17 2020
parent Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 13:25:08 UTC, Mike Parker wrote:
 Well, I was already using anonymous enums for compile-time
And, I should add, I have *never* seen C enums as an enumerated list of values. I've always seen them as an alternative for #defined constants because they're anonymous. It's *named* enums that I view as enumerated lists of values. So, in terms of vocabulary definitions, that was already a non-issue for me before I even discovered D.
Sep 17 2020
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/17/20 9:13 AM, Simen Kjærås wrote:

 To be clear: I don't mind 'enum' being used this way, but if I were to 
 do things over again, I would have used 'alias'.
fun fact: for a (very) brief time, D had a `manifest` keyword that did exactly what enum does in this instance (not even sure it made it into a release). enum is a head scratcher of a name, for sure. But it works out just fine once you get used to it. I think of it as "compile time". To be honest, for what it does, enum is a very poor name. But because it's consistent, it works. -Steve
Sep 17 2020
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 17, 2020 at 06:06:56PM -0400, Steven Schveighoffer via
Digitalmars-d-learn wrote:
 On 9/17/20 9:13 AM, Simen Kjærås wrote:
 
 To be clear: I don't mind 'enum' being used this way, but if I were
 to do things over again, I would have used 'alias'.
fun fact: for a (very) brief time, D had a `manifest` keyword that did exactly what enum does in this instance (not even sure it made it into a release). enum is a head scratcher of a name, for sure. But it works out just fine once you get used to it. I think of it as "compile time". To be honest, for what it does, enum is a very poor name. But because it's consistent, it works.
[...] In my mind, I just substitute 'enum' with 'manifest constant' and everything makes sense. ;-) T -- What are you when you run out of Monet? Baroque.
Sep 17 2020
prev sibling parent reply claptrap <clap trap.com> writes:
On Thursday, 17 September 2020 at 10:56:28 UTC, Mike Parker wrote:
 On Thursday, 17 September 2020 at 09:44:20 UTC, claptrap wrote:

 Seriously how it's implemented is irrelevant.
And to be clear, my point wasn't about how it's implemented. My point was that: enum { foo = 10; } and enum foo = 10; Are effectively the same thing, whether it's implemented that way or not. So why on earth would a new keyword be necessary?
Because they are not the same thing, one is a set of things, one is a single thing. That you say they are "effectively the same" is what Im getting at, just because they can be implemented the same, or one feature can be repurposed to serve the other need, doesnt mean they should. It's like... int x; int[1] x; They are effectively the same thing, a single int on the stack if declared locally, but they are conceptually different. And to me programming is not just about getting the job done but about being able to express the concept / design precisely. For example, this to me is utter nonsense... enum auto isTwoWayCompatible(alias fn, T1, T2); It makes about as much sense as using "enum" in place of "struct". If enum means manifiest constant, or compile time constant, then it makes more sense, as you allude to in a later post. But 'enum' is a terrible name for that and I dont think my brain will ever stop finding it incongruous.
Sep 17 2020
parent reply Mike Parker <aldacron gmail.com> writes:
On Thursday, 17 September 2020 at 22:25:47 UTC, claptrap wrote:

 If enum means manifiest constant, or compile time constant, 
 then it makes more sense, as you allude to in a later post. But 
 'enum' is a terrible name for that and I dont think my brain 
 will ever stop finding it incongruous.
And in my mind, what is a single-member enum if not a compile-time constant? This is why naming is hard.
Sep 17 2020
parent claptrap <clap trap.com> writes:
On Friday, 18 September 2020 at 02:49:30 UTC, Mike Parker wrote:
 On Thursday, 17 September 2020 at 22:25:47 UTC, claptrap wrote:

 If enum means manifiest constant, or compile time constant, 
 then it makes more sense, as you allude to in a later post. 
 But 'enum' is a terrible name for that and I dont think my 
 brain will ever stop finding it incongruous.
And in my mind, what is a single-member enum if not a compile-time constant? This is why naming is hard.
Yes all enum members are compile time constants, but not all compile time constants are enum members. The later is a subset of the former, but the reverse is not true. So the name implies the subset but the feature implements the superset.
Sep 18 2020
prev sibling parent Cecil Ward <cecil cecilward.com> writes:
On Thursday, 17 September 2020 at 01:57:39 UTC, Mike Parker wrote:
 On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward
 So can the result of declaring certain things with enum ever 
 have an _address_ then? (According to legit D code that is, 
 never mind the underlying implementation details, which may 
 not be observable)
No. Think of it as a named literal.
Thank you Mike. That’s exactly what I thought. And it’s another reason in favour of using enum - that it forbids address-taking and so declares that there will be none.
Oct 01 2020