Thread overview | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 13, 2011 Mutable enums | ||||
---|---|---|---|---|
| ||||
Do you remember if this bug is in Bugzilla? import std.algorithm; void main() { enum a = [3, 1, 2]; enum s = sort(a); assert(equal(a, [3, 1, 2])); assert(equal(s, [1, 2, 3])); } Bye, bearophile |
November 13, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, November 13, 2011 17:54:14 bearophile wrote:
> Do you remember if this bug is in Bugzilla?
>
>
> import std.algorithm;
> void main() {
> enum a = [3, 1, 2];
> enum s = sort(a);
> assert(equal(a, [3, 1, 2]));
> assert(equal(s, [1, 2, 3]));
> }
It's not a bug. Those an manifest constants. They're copy-pasted into whatever code you used them in. So,
enum a = [3, 1, 2];
enum s = sort(a);
is equivalent to
enum a = [3, 1, 2];
enum s = sort([3, 1, 2]);
a isn't altered at all, because a doesn't really exist. Notice that
assert(equal(a, [3, 1, 2]));
still passes. It's equivalent to
assert(equal([3, 1, 2], [3, 1, 2]));
- Jonathan M Davis
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> > import std.algorithm;
> > void main() {
> > enum a = [3, 1, 2];
> > enum s = sort(a);
> > assert(equal(a, [3, 1, 2]));
> > assert(equal(s, [1, 2, 3]));
> > }
>
> It's not a bug. Those an manifest constants. They're copy-pasted into whatever code you used them in. So,
>
> enum a = [3, 1, 2];
> enum s = sort(a);
>
> is equivalent to
>
> enum a = [3, 1, 2];
> enum s = sort([3, 1, 2]);
You are right, there's no DMD bug here. Yet, it's a bit surprising to sort in-place a "constant". I have to stop thinking of them as constants. I don't like this design of enums...
On the other hand this gives the error message I was looking for, until today I didn't even think about const enums:
import std.algorithm;
const enum a = [1, 2];
void main() {
sort(a);
}
So I guess I'll start using "cont enum" and "immutable enum" instead of enums :-)
Bye,
bearophile
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Sunday, November 13, 2011 19:02:01 bearophile wrote:
> Jonathan M Davis:
> > > import std.algorithm;
> > > void main() {
> > >
> > > enum a = [3, 1, 2];
> > > enum s = sort(a);
> > > assert(equal(a, [3, 1, 2]));
> > > assert(equal(s, [1, 2, 3]));
> > >
> > > }
> >
> > It's not a bug. Those an manifest constants. They're copy-pasted into whatever code you used them in. So,
> >
> > enum a = [3, 1, 2];
> > enum s = sort(a);
> >
> > is equivalent to
> >
> > enum a = [3, 1, 2];
> > enum s = sort([3, 1, 2]);
>
> You are right, there's no DMD bug here. Yet, it's a bit surprising to sort in-place a "constant". I have to stop thinking of them as constants. I don't like this design of enums...
>
> On the other hand this gives the error message I was looking for, until today I didn't even think about const enums:
>
> import std.algorithm;
> const enum a = [1, 2];
> void main() {
> sort(a);
> }
>
>
> So I guess I'll start using "cont enum" and "immutable enum" instead of enums :-)
It depends entirely on what you're trying to do. If you understand how manifest constants work, then they can be quite advantageous. What you probably really want for arrays though is not an enum but just a const or immutable module variable.
immutable a = [3, 1, 2];
Otherwise, you're allocating a new array every time you use the enum. So, use a manifest constant when you want to avoid having it take up any memory but don't care about whatever allocations may occur when it's used (primitive types such as ints being a prime example), whereas if you want an actual memory location for the constant and/or want it to be allocated only once, then use variable rather than an enum.
- Jonathan M Davis
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Mon, 14 Nov 2011 02:09:40 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> It depends entirely on what you're trying to do. If you understand how
> manifest constants work, then they can be quite advantageous. What you
> probably really want for arrays though is not an enum but just a const or
> immutable module variable.
>
> immutable a = [3, 1, 2];
>
> Otherwise, you're allocating a new array every time you use the enum. So, use
> a manifest constant when you want to avoid having it take up any memory but
> don't care about whatever allocations may occur when it's used (primitive
> types such as ints being a prime example), whereas if you want an actual
> memory location for the constant and/or want it to be allocated only once,
> then use variable rather than an enum.
>
> - Jonathan M Davis
Wait a second, it is definitely a bug. You can't modify an enum.
"immutable a = [3, 1, 2];" is practically "enum a = [3, 1, 2];".
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to so | On Monday, November 14, 2011 02:16:57 so wrote:
> On Mon, 14 Nov 2011 02:09:40 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
>
> wrote:
> > It depends entirely on what you're trying to do. If you understand how
> > manifest constants work, then they can be quite advantageous. What you
> > probably really want for arrays though is not an enum but just a const
> > or
> > immutable module variable.
> >
> > immutable a = [3, 1, 2];
> >
> > Otherwise, you're allocating a new array every time you use the enum.
> > So, use
> > a manifest constant when you want to avoid having it take up any memory
> > but
> > don't care about whatever allocations may occur when it's used
> > (primitive
> > types such as ints being a prime example), whereas if you want an actual
> > memory location for the constant and/or want it to be allocated only
> > once,
> > then use variable rather than an enum.
> >
> > - Jonathan M Davis
>
> Wait a second, it is definitely a bug. You can't modify an enum.
>
> "immutable a = [3, 1, 2];" is practically "enum a = [3, 1, 2];".
No. Those are two _very_ different things.
immutable a = [3, 1, 2];
creates a variable of type immutable(int[]). You takes up memory. You can take its address - e.g. &a. It exists even if you don't use it at all.
enum a = [3, 1, 2];
on the other hand, doesn't create any variable at all. It's what's called a manifest constant. It's a placeholder. It takes up no memory. You can't take its address. If you never use it, it doesn't end up in the generated program at all. Every use of a effectively copies the value of a to wherever its used. So,
enum a = [3, 1, 2];
sort(a);
is _identical_ to
sort([3, 1, 2]);
That means that if you use a in any code, it's copied in that code such that you could end up allocating a lot of memory that you didn't intend to if you heavily use manifest constants which are strings or arrays. But it also means that you get a new copy to use at each location, which can also be useful. And for types that don't end up on the heap (e.g. int), there's really no cost to it, and it actually is _more_ efficient (albeit marginally), since it avoids having to allocate any memory for the enum itself, since it's not a variable.
- Jonathan M Davis
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Mon, 14 Nov 2011 02:50:50 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> No. Those are two _very_ different things.
>
> immutable a = [3, 1, 2];
>
> creates a variable of type immutable(int[]). You takes up memory. You can take
> its address - e.g. &a. It exists even if you don't use it at all.
>
> enum a = [3, 1, 2];
>
> on the other hand, doesn't create any variable at all. It's what's called a
> manifest constant. It's a placeholder. It takes up no memory. You can't take
> its address. If you never use it, it doesn't end up in the generated program
> at all. Every use of a effectively copies the value of a to wherever its used.
> So,
>
> enum a = [3, 1, 2];
> sort(a);
>
> is _identical_ to
>
> sort([3, 1, 2]);
>
> That means that if you use a in any code, it's copied in that code such that
> you could end up allocating a lot of memory that you didn't intend to if you
> heavily use manifest constants which are strings or arrays. But it also means
> that you get a new copy to use at each location, which can also be useful. And
> for types that don't end up on the heap (e.g. int), there's really no cost to
> it, and it actually is _more_ efficient (albeit marginally), since it avoids
> having to allocate any memory for the enum itself, since it's not a variable.
>
> - Jonathan M Davis
Trying to remember the discussions on digitalmars.D regarding enum/immutable. There were contradicting opinions.
You ask the same question at two different times, you get at least two different answers, especially on this matter.
There was/is not a consensus on how it works or should work.
While i think enum/immutable are not same thing. Because with enum you mean it is a compile time value and compile time only, but immutable might rely on runtime initializers. So it differs here. This just means enum gives you more guaranties, not less.
enum a = 5;
immutable b = 6;
a = 3;
b = 3;
If the above code is invalid for both enum and immutable, so should the "in-place" sort case. I understand how it works, but it doesn't make any sense why it should work that way.
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to so | On Monday, November 14, 2011 04:03:54 so wrote:
> Trying to remember the discussions on digitalmars.D regarding
> enum/immutable. There were contradicting opinions.
> You ask the same question at two different times, you get at least two
> different answers, especially on this matter.
> There was/is not a consensus on how it works or should work.
>
> While i think enum/immutable are not same thing. Because with enum you mean it is a compile time value and compile time only, but immutable might rely on runtime initializers. So it differs here. This just means enum gives you more guaranties, not less.
>
> enum a = 5;
> immutable b = 6;
> a = 3;
> b = 3;
>
> If the above code is invalid for both enum and immutable, so should the "in-place" sort case. I understand how it works, but it doesn't make any sense why it should work that way.
It works exactly as it's designed to work. There are people who disagree with how it's designed, but it works exactly as designed. The above is invalid, because you can't assign to an enum - it's not a variable - and you can't assign to an immutable variable. sort works with an enum because you're passing it a valid array which is _not_ immutable. It's a new array just as if you'd passed it the enum's value directly. That may be surprising to some, but it's exactly as designed and is not a bug. If you think that it should work differently, then you're arguing against the current design, which is a completely different discussion.
- Jonathan M Davis
|
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 11/14/2011 01:02 AM, bearophile wrote: > Jonathan M Davis: > >>> import std.algorithm; >>> void main() { >>> enum a = [3, 1, 2]; >>> enum s = sort(a); >>> assert(equal(a, [3, 1, 2])); >>> assert(equal(s, [1, 2, 3])); >>> } >> >> It's not a bug. Those an manifest constants. They're copy-pasted into whatever >> code you used them in. So, >> >> enum a = [3, 1, 2]; >> enum s = sort(a); >> >> is equivalent to >> >> enum a = [3, 1, 2]; >> enum s = sort([3, 1, 2]); > > You are right, there's no DMD bug here. Yet, it's a bit surprising to sort in-place a "constant". I have to stop thinking of them as constants. I don't like this design of enums... It is the right design. Why should enum imply const or immutable? (or inout, for that matter). They are completely orthogonal. enum Enum{ opt1, opt2, } void main(){ auto moo = Enum.opt1; moo = Enum.opt2; // who would seriously want an error here??? } enum a = [1,2,3]; void main(){ auto x = a; x = [2,1,3]; // ditto } > > On the other hand this gives the error message I was looking for, until today I didn't even think about const enums: > > import std.algorithm; > const enum a = [1, 2]; > void main() { > sort(a); > } > > > So I guess I'll start using "cont enum" and "immutable enum" instead of enums :-) > You can do that, but they are not a full replacement. How would you get a sorted version of such an enum, for instance? =) |
November 14, 2011 Re: Mutable enums | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 11/14/2011 09:27 AM, Timon Gehr wrote:
> On 11/14/2011 01:02 AM, bearophile wrote:
>> Jonathan M Davis:
>>
>>>> import std.algorithm;
>>>> void main() {
>>>> enum a = [3, 1, 2];
>>>> enum s = sort(a);
>>>> assert(equal(a, [3, 1, 2]));
>>>> assert(equal(s, [1, 2, 3]));
>>>> }
>>>
>>> It's not a bug. Those an manifest constants. They're copy-pasted into
>>> whatever
>>> code you used them in. So,
>>>
>>> enum a = [3, 1, 2];
>>> enum s = sort(a);
>>>
>>> is equivalent to
>>>
>>> enum a = [3, 1, 2];
>>> enum s = sort([3, 1, 2]);
>>
>> You are right, there's no DMD bug here. Yet, it's a bit surprising to
>> sort in-place a "constant". I have to stop thinking of them as
>> constants. I don't like this design of enums...
>
> It is the right design. Why should enum imply const or immutable? (or
> inout, for that matter). They are completely orthogonal.
>
> enum Enum{
> opt1,
> opt2,
> }
>
> void main(){
> auto moo = Enum.opt1;
> moo = Enum.opt2; // who would seriously want an error here???
> }
>
>
> enum a = [1,2,3];
>
> void main(){
> auto x = a;
> x = [2,1,3]; // ditto
> }
>
>
>>
>> On the other hand this gives the error message I was looking for,
>> until today I didn't even think about const enums:
>>
>> import std.algorithm;
>> const enum a = [1, 2];
>> void main() {
>> sort(a);
>> }
>>
>>
>> So I guess I'll start using "cont enum" and "immutable enum" instead
>> of enums :-)
>>
>
> You can do that, but they are not a full replacement. How would you get
> a sorted version of such an enum, for instance? =)
(.dup, obviously.)
|
Copyright © 1999-2021 by the D Language Foundation