Const sucks

charles charlie at d.com
Wed Sep 12 15:45:47 PDT 2007


Yes.  Const does suck.

Walter Bright wrote:

> 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