Const sucks
Walter Bright
newshound1 at digitalmars.com
Mon Sep 10 12:15:09 PDT 2007
Const, final, invariant, head const, tail const, it's grown into a
monster. It tries to cover all the bases, but in doing so is simply not
understandable.
Andrei and Bartosz have spent some time together going back to square
one with what are we trying to achieve with const, and came up with
another proposal.
What we are trying to achieve:
a) utility for functional programming
b) better modularity by self-documenting interfaces better
c) be able to treat reference types as if they were value types (i.e.
strings should behave to the user like value types, even though they are
references)
The insights they came up with were:
1) final (i.e. 'head const') is not necessary for a, b or c. final is a
local thing, and not strictly necessary.
2) tail const can be handled in other ways, read on
So, what we are left with is:
o no more final
o const and invariant now mean "fully const" and "fully invariant",
where fully means "head and tail combined":
const int x = 0; // x is constant
const int* p = &x; // neither p nor *p can be changed
const(int*) p = &x; // neither p nor *p can be changed
const(int)* p = &x; // p can change, *p cannot be changed
o const and invariant are transitive. There is no way to specify a
(pointer to)(const pointer to)(mutable int).
o tail invariant for an array or pointer type can be done using the
existing syntax:
invariant(char)[] s; // string, i.e. an array of invariant chars
const(T)* p; // pointer to tail const T
o tail const of a struct would have to be done by making the struct a
template:
struct S(T) { T member; }
S!(int) // tail mutable
S!(const(int)) // tail const
o one can construct a template to generically produce tail const or
tail invariant versions of a type.
o it will be illegal to attempt to change the key value of a foreach
loop, but the compiler will not be able to diagnose all attempts to do so
o static const/invariant means the initializer is evaluated at compile
time. non-static const/invariant means it is evaluated at run time.
o no initializer means it is assigned in the corresponding constructor.
o const/invariant declarations will always allocate memory (so their
addresses can be taken)
o So, we still need a method to declare a constant that will not
consume memory. We'll co-opt the future macro syntax for that:
macro x = 3;
macro s = "hello";
More information about the Digitalmars-d
mailing list