D const design rationale

Kristian Kilpi kjkilpi at gmail.com
Sun Jun 24 04:41:59 PDT 2007


On Sat, 23 Jun 2007 17:22:41 +0300, Reiner Pope <some at address.com> wrote:
> I think that invariant-as-storage-class vs. const-as-storage-class is a  
> false dichotomy, and also that they are incorrectly associated with the  
> completely different type-constructors, const() and invariant().
>
>
> As storage classes, const and invariant both mean "compile-time  
> constant" -- their initializers must be evaluatable at compile time, and  
> their data need not be stored in memory.
>
> However, apparently, data referred to by const-as-storage-class could  
> actually be liable to change (this is cited as the difference between  
> const-as-storage-class and invariant-as-storage-class).
>
> Yet this seems to clash with the idea of being initialized at compile  
> time: in order for the data pointed to by const-as-storage-class to be  
> changed by another reference, there must be a mutable pointer from which  
> such a variable is initialized. Something like:
>
> void main() {
>     int a = 10;
>     int* p = &a; // here's our mutable view
>     const int* cp = &a; // here's our const-as-storage-class
> }
>
> At the moment, this doesn't compile, because &a is not evaluatable at  
> compile time (even though the address of a is statically known).  
> Assuming this is never supported (and I don't think that it should be),  
> then the data pointed to by a const-storage-class variable can never be  
> changed, so the data is really invariant. In that case,  
> const-as-storage-class should be abolished, as it is identical to  
> invariant-as-storage-class.[1]
>
> ---
>
> I also think that the idea of a "compile time constant" is distinct from  
> invariant-as-type-constructor. For the purposes of clarity, I think it  
> would ideally be better to make this distinction clear, and give this  
> storage class a different name (sorry about Yet Another Keyword). I  
> think 'define' could make sense:
>
>      define PI = 3.14;
>      define LanguageName = "D Programming Language";
>
> This also emphasises the similarity in meaning to #define.
>
> Of course, typeof(LanguageName) == invariant(char[])
>
> ---
>
> [1] Although the data pointed to by const-as-storage-class *is*  
> invariant, the type system doesn't believe it. The following doesn't  
> compile (correctly so, according to the specs)
>
>      const char[] a = "abc";
>      invariant char[] b = a;
>
> but how can the data in 'a' possibly change?
>
>
>
>     Reiner


I also thought about using a different keyword for compile-time constants.
I used 'literal' instead of 'define' though. :)

   const int a = 10;  //ok, compile-time constant

   const int b = f();  //error (assuming 'f()' cannot be evaluted at  
compile time)

I think that can be a bit confusing. I would like that 'b' would be  
immutable,
not a compile-time constant. (Yep, I know, 'final' is for that, but  
still...)


After that change, 'final' would be useless for value types.
Unfortunately, refence types (and pointers) are more problematic.

Old: const int v = 10;
New: literal int v = 10;

Old: const int v = f();
New: const int v = f();

Old: final const(MyClass) v;
New: const MyClass v;

Old: const(MyClass) v;
New: const(MyClass) v;

Old: final MyClass v;
New: ?



More information about the Digitalmars-d mailing list