Proposal - Revised Syntax for const and final

Reiner Pope some at address.com
Sat Sep 8 20:16:25 PDT 2007


Janice Caron wrote:
> The fact that
> const(int**) s;
> const(int*)* s;
> both mean the same thing is highly counterintuitive.

I agree. However, I think this problem can be solved with much smaller
changes.

The syntax would be consistent if const(T) was a type constructor which 
gave a type like T, but with tail const. Consider the struct A, defined 
below:

struct A
{
     int x;
}

The types const(A) and A should behave identically, as there is no 
"tail" to be made constant. The following code is valid:

const(A) a;
a.x = 5; // nothing wrong here

Now consider the array type constructor, [], which takes a type T and 
returns the array type T[]. For this to be a sensible type constructor, 
any operation permitted on T should be permitted on the elements of T[]. 
   This is true of user-land type constructors (templated structs, etc) 
but not of pointers and arrays. Consider:

struct MyArray(T)
{
     T firstElem;
}

This is a valid type constructor, which takes a type T and returns an 
array of T (admittedly, the array isn't very interesting -- it only has 
one element -- but you can still call it an array). Now contrast the use:

const(A)[] b;
b[0].x = 5; // error, b[0].x is not mutable

MyArray!(const(A)) c;
c.firstElem.x = 5; // fine


Now you might complain and point out that const(A)[] actually contains A 
behind a pointer, whereas MyArray!(const(A)) stores A directly. Well, we 
solve that problem by instead declaring MyArray as a class:

class MyArray2(T)
{
     T firstElem;
}

MyArray2!(const(A)) c2;
c2.firstElem.x = 5; // still fine

[Note that I'm showing the reference behaviour with classes and not with 
pointers because both pointers and arrays have this "taint" that I'm 
trying to show is inconsistent.]


This is a very inconsistent behaviour. We used to have the property that 
  any member accessible of an instance of T is also accessible of an 
element of T[]. This is no longer true, and it means that generic code 
may require extra special cases.


The way to fix it is simply to remove the special cases, which exist for

const(T)*

and

const(T)[]

In both of these cases, the data pointed to should be tail const. 
Currently, it is head *and* tail const.



    -- Reiner



More information about the Digitalmars-d mailing list