www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Can enum and immutable be unified?

reply Ary Borenszweig <ary esperanto.org.ar> writes:
Michiel Helvensteijn escribió:
 Walter Bright wrote:

 immutable - data that cannot change or be changed (imagine it is stored
 in ROM)

 const - read only view of data, you cannot change it but others can

 enum - compile time constant, has no storage

 The only place these overlap is in the declaration of symbolic
 constants. C++ has all three, but in a way that is context dependent
 that very few people are aware of.
Aren't immutable and enum the same thing? At least to the programmer?
Yesterday I was thiking the same thing. I think the only difference to the programmer between those is that you can take the address of something immutable, but can't take the address of a compile time constant. Now I wonder why would you like to take the address of something that's immutable. The times I remember passing something's address is to change it, something like: int x = 10; foo(&x); // now x might have changed But immutable variables cannot change, so no need to pass it by reference. The other usage is performance. If it's an immutable big struct you might want to pass it by reference instead of copying the whole thing. If you can't pass a reference to something immutable you couldn't do with this optimization. But in this case, the compiler could choose to rewrite mentions to big immutable variables as references to those in a transparent way to the programmer. Of course this is harder for the compiler writer, but it's much easier for the user. (as a starting point the compiler could do without this optimization and see if the users are having problems without it) I can't come up with other cases where you'd want to pass a reference to something immutable. So let's suppose we don't need to take an immutable varaible's address. We get rid of "enum" then and unify "immutable" and "enum" into the single "immutable" keyword. The compiler still has to determine what to put in ROM and what not. But I think this one is easy: primitive types can go in ROM, also maybe small immutable structs, maybe primitive arrays, but not classes or references to classes. Is there something fundamentally wrong with this reasoning?
Jul 23 2009
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Ary Borenszweig escribió:
 Michiel Helvensteijn escribió:
  > Walter Bright wrote:
  >
  >> immutable - data that cannot change or be changed (imagine it is stored
  >> in ROM)
  >>
  >> const - read only view of data, you cannot change it but others can
  >>
  >> enum - compile time constant, has no storage
  >>
  >> The only place these overlap is in the declaration of symbolic
  >> constants. C++ has all three, but in a way that is context dependent
  >> that very few people are aware of.
  >
  > Aren't immutable and enum the same thing? At least to the programmer?
 
 Yesterday I was thiking the same thing. I think the only difference to 
 the programmer between those is that you can take the address of 
 something immutable, but can't take the address of a compile time constant.
 
 Now I wonder why would you like to take the address of something that's 
 immutable. The times I remember passing something's address is to change 
 it, something like:
 
 int x = 10;
 foo(&x);
 // now x might have changed
 
 But immutable variables cannot change, so no need to pass it by reference.
 
 The other usage is performance. If it's an immutable big struct you 
 might want to pass it by reference instead of copying the whole thing. 
 If you can't pass a reference to something immutable you couldn't do 
 with this optimization. But in this case, the compiler could choose to 
 rewrite mentions to big immutable variables as references to those in a 
 transparent way to the programmer. Of course this is harder for the 
 compiler writer, but it's much easier for the user.
 
 (as a starting point the compiler could do without this optimization and 
 see if the users are having problems without it)
 
 I can't come up with other cases where you'd want to pass a reference to 
 something immutable.
 
 So let's suppose we don't need to take an immutable varaible's address. 
 We get rid of "enum" then and unify "immutable" and "enum" into the 
 single "immutable" keyword. The compiler still has to determine what to 
 put in ROM and what not. But I think this one is easy: primitive types 
 can go in ROM, also maybe small immutable structs, maybe primitive 
 arrays, but not classes or references to classes.
Sorry, I wanted to write that the compiler can choose what things are compile-time constants and what things should go into ROM. Primitives, small structs, etc, should be compile-time constants.
Jul 23 2009
parent "Nick Sabalausky" <a a.a> writes:
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message 
news:h49nfn$114b$1 digitalmars.com...
 So let's suppose we don't need to take an immutable varaible's address. 
 We get rid of "enum" then and unify "immutable" and "enum" into the 
 single "immutable" keyword. The compiler still has to determine what to 
 put in ROM and what not. But I think this one is easy: primitive types 
 can go in ROM, also maybe small immutable structs, maybe primitive 
 arrays, but not classes or references to classes.
Sorry, I wanted to write that the compiler can choose what things are compile-time constants and what things should go into ROM. Primitives, small structs, etc, should be compile-time constants.
For many embedded uses, you would need to have some way to be able to say "This must be in ROM" (and probably at a specific address) so that it can be accessed by more than just the firmware. Hmm, but then again, I suppose that would probably be better handled by a linker that supports embedding of resources. It's not a bad idea IMO. And you could even have an "optimize for size" setting that keeps all immutable types out of ROM (wherever possible) without the programmer needing to change code. I'd still want to keep "enum" for *real* enumerations, though.
Jul 23 2009
prev sibling parent reply Don <nospam nospam.com> writes:
Ary Borenszweig wrote:
 Michiel Helvensteijn escribió:
  > Walter Bright wrote:
  >
  >> immutable - data that cannot change or be changed (imagine it is stored
  >> in ROM)
  >>
  >> const - read only view of data, you cannot change it but others can
  >>
  >> enum - compile time constant, has no storage
  >>
  >> The only place these overlap is in the declaration of symbolic
  >> constants. C++ has all three, but in a way that is context dependent
  >> that very few people are aware of.
  >
  > Aren't immutable and enum the same thing? At least to the programmer?
 
 Yesterday I was thiking the same thing. I think the only difference to 
 the programmer between those is that you can take the address of 
 something immutable, but can't take the address of a compile time constant.
 
 Now I wonder why would you like to take the address of something that's 
 immutable. The times I remember passing something's address is to change 
 it, something like:
 
 int x = 10;
 foo(&x);
 // now x might have changed
 
 But immutable variables cannot change, so no need to pass it by reference.
 
 The other usage is performance. If it's an immutable big struct you 
 might want to pass it by reference instead of copying the whole thing. 
 If you can't pass a reference to something immutable you couldn't do 
 with this optimization. But in this case, the compiler could choose to 
 rewrite mentions to big immutable variables as references to those in a 
 transparent way to the programmer. Of course this is harder for the 
 compiler writer, but it's much easier for the user.
 
 (as a starting point the compiler could do without this optimization and 
 see if the users are having problems without it)
 
 I can't come up with other cases where you'd want to pass a reference to 
 something immutable.
 
 So let's suppose we don't need to take an immutable varaible's address. 
 We get rid of "enum" then and unify "immutable" and "enum" into the 
 single "immutable" keyword. The compiler still has to determine what to 
 put in ROM and what not. But I think this one is easy: primitive types 
 can go in ROM, also maybe small immutable structs, maybe primitive 
 arrays, but not classes or references to classes.
 
 Is there something fundamentally wrong with this reasoning?
AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist.
Jul 23 2009
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Don wrote:
 Ary Borenszweig wrote:
 Michiel Helvensteijn escribió:
  > Walter Bright wrote:
  >
  >> immutable - data that cannot change or be changed (imagine it is 
 stored
  >> in ROM)
  >>
  >> const - read only view of data, you cannot change it but others can
  >>
  >> enum - compile time constant, has no storage
  >>
  >> The only place these overlap is in the declaration of symbolic
  >> constants. C++ has all three, but in a way that is context dependent
  >> that very few people are aware of.
  >
  > Aren't immutable and enum the same thing? At least to the programmer?

 Yesterday I was thiking the same thing. I think the only difference to 
 the programmer between those is that you can take the address of 
 something immutable, but can't take the address of a compile time 
 constant.

 Now I wonder why would you like to take the address of something 
 that's immutable. The times I remember passing something's address is 
 to change it, something like:

 int x = 10;
 foo(&x);
 // now x might have changed

 But immutable variables cannot change, so no need to pass it by 
 reference.

 The other usage is performance. If it's an immutable big struct you 
 might want to pass it by reference instead of copying the whole thing. 
 If you can't pass a reference to something immutable you couldn't do 
 with this optimization. But in this case, the compiler could choose to 
 rewrite mentions to big immutable variables as references to those in 
 a transparent way to the programmer. Of course this is harder for the 
 compiler writer, but it's much easier for the user.

 (as a starting point the compiler could do without this optimization 
 and see if the users are having problems without it)

 I can't come up with other cases where you'd want to pass a reference 
 to something immutable.

 So let's suppose we don't need to take an immutable varaible's 
 address. We get rid of "enum" then and unify "immutable" and "enum" 
 into the single "immutable" keyword. The compiler still has to 
 determine what to put in ROM and what not. But I think this one is 
 easy: primitive types can go in ROM, also maybe small immutable 
 structs, maybe primitive arrays, but not classes or references to 
 classes.

 Is there something fundamentally wrong with this reasoning?
AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist.
Since objconv works with OMF now, how hard would it be to get a workflow going to use a different linker on Windows? Every other post these days seems to be "oh, it's an optlink issue"
Jul 23 2009
parent reply Don <nospam nospam.com> writes:
Robert Fraser wrote:
 Don wrote:
 Ary Borenszweig wrote:
 Michiel Helvensteijn escribió:
  > Walter Bright wrote:
  >
  >> immutable - data that cannot change or be changed (imagine it is 
 stored
  >> in ROM)
  >>
  >> const - read only view of data, you cannot change it but others can
  >>
  >> enum - compile time constant, has no storage
  >>
  >> The only place these overlap is in the declaration of symbolic
  >> constants. C++ has all three, but in a way that is context dependent
  >> that very few people are aware of.
  >
  > Aren't immutable and enum the same thing? At least to the programmer?

 Yesterday I was thiking the same thing. I think the only difference 
 to the programmer between those is that you can take the address of 
 something immutable, but can't take the address of a compile time 
 constant.

 Now I wonder why would you like to take the address of something 
 that's immutable. The times I remember passing something's address is 
 to change it, something like:

 int x = 10;
 foo(&x);
 // now x might have changed

 But immutable variables cannot change, so no need to pass it by 
 reference.

 The other usage is performance. If it's an immutable big struct you 
 might want to pass it by reference instead of copying the whole 
 thing. If you can't pass a reference to something immutable you 
 couldn't do with this optimization. But in this case, the compiler 
 could choose to rewrite mentions to big immutable variables as 
 references to those in a transparent way to the programmer. Of course 
 this is harder for the compiler writer, but it's much easier for the 
 user.

 (as a starting point the compiler could do without this optimization 
 and see if the users are having problems without it)

 I can't come up with other cases where you'd want to pass a reference 
 to something immutable.

 So let's suppose we don't need to take an immutable varaible's 
 address. We get rid of "enum" then and unify "immutable" and "enum" 
 into the single "immutable" keyword. The compiler still has to 
 determine what to put in ROM and what not. But I think this one is 
 easy: primitive types can go in ROM, also maybe small immutable 
 structs, maybe primitive arrays, but not classes or references to 
 classes.

 Is there something fundamentally wrong with this reasoning?
AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist.
Since objconv works with OMF now, how hard would it be to get a workflow going to use a different linker on Windows? Every other post these days seems to be "oh, it's an optlink issue"
objconv can disassemble OMF now, but it can't yet convert COMDAT sections, so it can't convert them to ELF or COFF. Might not be so difficult, if someone wanted to do it. D's use of COMDATs is not so complicated.
Jul 24 2009
parent Robert Fraser <fraserofthenight gmail.com> writes:
Don wrote:
 Robert Fraser wrote:
 Don wrote:
 Ary Borenszweig wrote:
 Michiel Helvensteijn escribió:
  > Walter Bright wrote:
  >
  >> immutable - data that cannot change or be changed (imagine it is 
 stored
  >> in ROM)
  >>
  >> const - read only view of data, you cannot change it but others can
  >>
  >> enum - compile time constant, has no storage
  >>
  >> The only place these overlap is in the declaration of symbolic
  >> constants. C++ has all three, but in a way that is context 
 dependent
  >> that very few people are aware of.
  >
  > Aren't immutable and enum the same thing? At least to the 
 programmer?

 Yesterday I was thiking the same thing. I think the only difference 
 to the programmer between those is that you can take the address of 
 something immutable, but can't take the address of a compile time 
 constant.

 Now I wonder why would you like to take the address of something 
 that's immutable. The times I remember passing something's address 
 is to change it, something like:

 int x = 10;
 foo(&x);
 // now x might have changed

 But immutable variables cannot change, so no need to pass it by 
 reference.

 The other usage is performance. If it's an immutable big struct you 
 might want to pass it by reference instead of copying the whole 
 thing. If you can't pass a reference to something immutable you 
 couldn't do with this optimization. But in this case, the compiler 
 could choose to rewrite mentions to big immutable variables as 
 references to those in a transparent way to the programmer. Of 
 course this is harder for the compiler writer, but it's much easier 
 for the user.

 (as a starting point the compiler could do without this optimization 
 and see if the users are having problems without it)

 I can't come up with other cases where you'd want to pass a 
 reference to something immutable.

 So let's suppose we don't need to take an immutable varaible's 
 address. We get rid of "enum" then and unify "immutable" and "enum" 
 into the single "immutable" keyword. The compiler still has to 
 determine what to put in ROM and what not. But I think this one is 
 easy: primitive types can go in ROM, also maybe small immutable 
 structs, maybe primitive arrays, but not classes or references to 
 classes.

 Is there something fundamentally wrong with this reasoning?
AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist.
Since objconv works with OMF now, how hard would it be to get a workflow going to use a different linker on Windows? Every other post these days seems to be "oh, it's an optlink issue"
objconv can disassemble OMF now, but it can't yet convert COMDAT sections, so it can't convert them to ELF or COFF. Might not be so difficult, if someone wanted to do it. D's use of COMDATs is not so complicated.
I would _love_ to see being able to use another (MS?) linker on WIndows
Jul 25 2009