Thread overview
Regarding fixed size arrays
Mar 15, 2014
bearophile
Mar 15, 2014
Meta
Mar 15, 2014
Meta
Mar 15, 2014
Chris Williams
Mar 15, 2014
bearophile
March 15, 2014
A small question about the D type system. Currently this code doesn't compile:


int[5] foo(int[2] a, int[3] b) {
    return a ~ b;
}
void main() {}



test.d(2,12): Error: cannot implicitly convert expression (cast(int[])a ~ cast(int[])b) of type int[] to int[5]


But I think it's easy to modify D/DMD to support code like that. (A small optimization can even remove any heap allocations from code like that, because in D fixed-size arrays are passed and returned by value).

Do you think it's useful/worth supporting code like that?

Bye,
bearophile
March 15, 2014
On Saturday, 15 March 2014 at 00:11:22 UTC, bearophile wrote:
> Do you think it's useful/worth supporting code like that?

Yes, I'm surprised that doesn't currently work. I hate how static arrays throw away their length at the drop of a hat. In the meantime, here's a workaround:

T[N + M] concat(T, int N, int M)(T[N] arr1, T[M] arr2)
{
	T[N + M] result = arr1 ~ arr2;
	
	return result;
}

void main()
{
	int[3] arr1;
	int[2] arr2;
	int[5] arr3 = concat(arr1, arr2);

        //Error: array length mismatch
        int[6] arr4 = concat(arr1, arr2);
}

March 15, 2014
On Saturday, 15 March 2014 at 00:11:22 UTC, bearophile wrote:
> Do you think it's useful/worth supporting code like that?

My expectation would be that your code is implicitly the same as:

int[5] foo(int[2] a, int[3] b) {
   int[5] staticArray;
   int[] dynamicArray = a ~ b;
   staticArray = dynamicArray;
   return staticArray;
}

Based on the information at http://dlang.org/arrays.html, my expectation would be that a copy requires the slice operator, which isn't in your code. Thus it's trying to initialize staticArray as a new dynamic array -- which obviously wouldn't work.

Since your code doesn't have access to the hidden staticArray variable, there's no way to write the correct code:

staticArray[] = dynamicArray;

Short of changing the standard to consider "a = b" to be equivalent to "a[] = b" when both a and b are arrays, I don't think your code should be handled. And I think such a change would be dangerous.

The following works, and I think is probably acceptable.

int[5] foo(int[2] a, int[3] b) {
    int[5] ret;
    ret[] = a ~ b;
    return ret;
}

March 15, 2014
On Saturday, 15 March 2014 at 01:14:02 UTC, Meta wrote:
> On Saturday, 15 March 2014 at 00:11:22 UTC, bearophile wrote:
>> Do you think it's useful/worth supporting code like that?
>
> Yes, I'm surprised that doesn't currently work. I hate how static arrays throw away their length at the drop of a hat. In the meantime, here's a workaround:
>
> T[N + M] concat(T, int N, int M)(T[N] arr1, T[M] arr2)
> {
> 	T[N + M] result = arr1 ~ arr2;
> 	
> 	return result;
> }
>
> void main()
> {
> 	int[3] arr1;
> 	int[2] arr2;
> 	int[5] arr3 = concat(arr1, arr2);
>
>         //Error: array length mismatch
>         int[6] arr4 = concat(arr1, arr2);
> }

Err, sorry, the lengths as template args aren't necessary. Your example works fine with this small change:

int[5] foo(int[2] a, int[3] b)
{
    int[5] result = a ~ b;
	
    return result;
}

Though I am happy about how powerful D's pattern matching in template arguments is.
March 15, 2014
Chris Williams:

> Short of changing the standard to consider "a = b" to be equivalent to "a[] = b" when both a and b are arrays, I don't think your code should be handled. And I think such a change would be dangerous..

I think I was the one that has asked for the systematic introduction of such syntax, and Kenji has implemented it after lot of discussions.

Probably later I'll add a bit more comments here.

Bye,
bearophile