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