"headconst" dynamic arrays?

bearophile bearophileHUGS at lycos.com
Wed Aug 31 01:22:21 PDT 2011


(Probably this topic was already discussed in past, if this is the case them I am sorry).

I like to use both static and dynamic languages. In a statically typed language as D if I have to pay for type annotations and related troubles, I want them to give me back as much as possible.

Putting "in" (or const/immutable) before a function argument makes it constant, this is useful for code documentation, to avoid changing the argument by mistake inside the function, and for stronger purity.

In this function foo() the argument 'arr' can't be const because the function has to modify its contents somehow. But often even if I have to modify the given array contents, I don't have to change its length or rebind its ptr (assign it to another array). (In this program 'a' in the main() will not change its length nor the memory it refers too, but the bug is present still, because the writeln gives a wrong output) (sometimes the argument is a string, it's the same thing).


import std.stdio;
void foo(int[] arr) {
    // some code here...
    arr.length += 1; // a bug
    // some code here...
    foreach (ref x; arr)
        x++;
    writeln(arr);
}
void main() {
    int[] a = [1, 2, 3];
    foo(a);
}


So in my code I sometimes like "headconst dynamic array", that is an array that allows changes in its contents but not its length. Currently in D there is no way to specify this kind of array (there is a way to specify tailconst arrays, like const(int)[], but this is the opposite of what I'm looking for).

A possible curious syntax :-)

void foo(int const([]) arr) {
    // some code here...
    arr.length += 1; // problem caught!
    arr = new int[5]; // not allowed
    // some code here...
    foreach (ref x; arr)
        x++;
    writeln(arr);
}


The space between int and const is necessary, you can't write it as:
void foo(intconst([]) arr) {

One alternative syntax (only one syntax is accepted, of course):
void foo(int(const[]) arr) {


That curious first syntax seems to work for nD arrays too:

Both dimensions are headconst:
void bar(int const([][]) mat2d) {
Or:
void bar(int (const[][]) mat2d) {

Only 2 dimensions of 3 are headconst:
void spam(int const([][])[] mat3d) {
Or:
void spam(int (const[][])[] mat3d) {


Is this too much complexity for a corner case? Most dynamic arrays are passed with "in/const". Is this little problem better solved with user/library code?

Bye,
bearophile


More information about the Digitalmars-d mailing list