Jump to page: 1 2
Thread overview
"headconst" dynamic arrays?
Aug 31, 2011
bearophile
Aug 31, 2011
Christophe
Aug 31, 2011
bearophile
Aug 31, 2011
Jonathan M Davis
Aug 31, 2011
bearophile
HeadConst library type (was: "headconst" dynamic arrays?)
Aug 31, 2011
dsimcha
Sep 01, 2011
bearophile
Sep 01, 2011
bearophile
Sep 01, 2011
Martin Nowak
Aug 31, 2011
Kagamin
Aug 31, 2011
bearophile
Aug 31, 2011
Kagamin
Aug 31, 2011
bearophile
Aug 31, 2011
Kagamin
Aug 31, 2011
bearophile
Aug 31, 2011
Marco Leise
Aug 31, 2011
bearophile
Aug 31, 2011
Marco Leise
August 31, 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
August 31, 2011

headconst seems a very useful thing.

> void foo(int(const[]) arr)
int(const[]) looks like a function signature, I would avoid it.

-- 
Christophe Travert
August 31, 2011
Christophe Travert:

> headconst seems a very useful thing.

In C you are allowed to write:


#include <stdio.h>
void foo(int * const arr, const int arr_len) {
    // some code here...
    arr_len += 1; // a bug
    int arr2[] = {10, 20, 30, 40};
    arr = arr2;
    // some code here...
    for (int i = 0; i < arr_len; i++)
        arr[i]++;
    for (int i = 0; i < arr_len; i++)
        printf("%d ", arr[i]);
    putchar('\n');
}
int main() {
    int a[] = {1, 2, 3};
    foo(a, 3);
    return 0;
}


Here GCC 4.6.1 gives:
test.c: In function 'foo':
test.c:4:5: error: assignment of read-only parameter 'arr_len'
test.c:6:5: error: assignment of read-only parameter 'arr'


Dynamic arrays that don't change their length and don't allow rebinding, but allow changes in their contents, are useful. I use arrays every day in D and this desire arises now and then. It's hard to deny this.

But the point are: how much useful it is in D? Is the added language complexity worth it? Is it possible to design semantically sound conversions between the various kind of arrays? Is it possible/better a library solution for it?


> > void foo(int(const[]) arr)
> int(const[]) looks like a function signature, I would avoid it.

OK. The first syntax doesn't have this problem.

Bye,
bearophile
August 31, 2011
On Wednesday, August 31, 2011 05:42:07 bearophile wrote:
> Dynamic arrays that don't change their length and don't allow rebinding, but allow changes in their contents, are useful. I use arrays every day in D and this desire arises now and then. It's hard to deny this.

Um. Just don't change their length? Sure, it would be nice to be able to have this feature, but it's hardly the only issue in D where you can't have a particular combination of const and mutable due to how D's const works, and really, all you have to do is not alter the length of the array in the function that it's passed to. So, yes, it would be nice, but I don't think that it's a big deal. Of far greater importance is being able to make the elements const, and we can do that quite easily already.

- Jonathan M Davis
August 31, 2011
bearophile Wrote:

> 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?

Looks like a coding style. Can be done with a source analyzer or a compiler switch.
August 31, 2011
Kagamin:

> Looks like a coding style. Can be done with a source analyzer or a compiler switch.

I don't understand. What do you mean?

Bye,
bearophile
August 31, 2011
bearophile Wrote:

> I don't understand. What do you mean?

It's not needed to extend type system. Compiler can check you don't set arguments indiscriminately. I believe some source analyzer already does it.
August 31, 2011
Kagamin:

> It's not needed to extend type system. Compiler can check you don't set arguments indiscriminately. I believe some source analyzer already does it.

Some functions need to do everything on a given array, while in other functions I just want to change the array contents. How can the source analyzer tell them apart and show some warnings only on the second kind of functions, without specific annotations?

Bye,
bearophile
August 31, 2011
Jonathan M Davis:

> it's hardly the only issue in D where you can't have a particular combination of const and mutable due to how D's const works,

Right. The difference between this idea and those particular combinations is that I think this situation has a solution and a syntax.

Bye,
bearophile
August 31, 2011
Have we considered the obvious library head-const solution?

struct HeadConst(T) {
    T __payload;

    T __get() {
        return __payload;
    }

    alias __get this;
}

HeadConst!T headConst(T)(T stuff) { return typeof(return)(stuff); }

Usage:

auto headConstArray = headConst([1, 2, 3]);

The only problem I see is that you'd get unnecessary copying of structs with postblits.  IMHO, though, the language spec should be relaxed to allow copying to be elided due to function inlining.
« First   ‹ Prev
1 2