October 10, 2020
cross-post here for general discussion about the library & language.

https://forum.dlang.org/post/naaxgyuzahnhjltblbtp@forum.dlang.org

On Sunday, 6 December 2015 at 12:27:49 UTC, cym13 wrote:
> On Sunday, 6 December 2015 at 12:23:05 UTC, Tim K. wrote:
>> Hi! I have the following code:
>>
>>     int main(string[] argv)
>>     {
>>         import std.algorithm: sum;
>>         import std.stdio: writeln;
>>
>>         uint[3] a1 = [1, 2, 3];
>>         uint[] a2;
>>         for (int i = 1; i <= 3; ++i)
>>             a2 ~= i;
>>
>>         writeln("a1: ", sum(a1));
>>         writeln("a2: ", sum(a2));
>>         return 0;
>>     }
>>
>> This throws the error:
>> dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are:
>> /usr/include/dmd/phobos/std/algorithm/iteration.d(3916):
>>  std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))
>> /usr/include/dmd/phobos/std/algorithm/iteration.d(3927):
>>  std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front)))
>>
>>
>> So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays?
>>
>>
>> Regards
>
> So that you do not shoot yourself in the foot too easily. A static array is a value type so it is passed by value to functions. If you pass a 1M array to a function... well, I guesse you don't want to do that.

Can the template func `sum()` be made to take `ref` of a static array?

> The solution is to slice it:   a1[].sum;   That way you avoid the problem.

While I understand the explanation of the current behavior, and the work-around, this inconstancy of making func calls means either the library, or the language leaves something to be desired: i.e

dynamic array and static array cannot be used interchangeably: (sure I'm not talking about array decl / allocation, the user have to take different actions) I'm talking about a simple function call to calc the sum of the array.
```
  sum(static_array[]);   // v.s.
  sum(dynamic_array);
```

For example, if the user first decl a static array for fast prototyping, and later changed mind to use dynamic array, then s/he need to change the call all over the places.


(I hope you are not telling me, every time people should use:
```
  array_func(any_array[]);
```
is the correct D-idiom to use array in a func call)

October 10, 2020
On 10/10/20 3:10 PM, mw wrote:
> cross-post here for general discussion about the library & language.
> 
> https://forum.dlang.org/post/naaxgyuzahnhjltblbtp@forum.dlang.org
> 
> On Sunday, 6 December 2015 at 12:27:49 UTC, cym13 wrote:
>> On Sunday, 6 December 2015 at 12:23:05 UTC, Tim K. wrote:
>>> Hi! I have the following code:
>>>
>>>     int main(string[] argv)
>>>     {
>>>         import std.algorithm: sum;
>>>         import std.stdio: writeln;
>>>
>>>         uint[3] a1 = [1, 2, 3];
>>>         uint[] a2;
>>>         for (int i = 1; i <= 3; ++i)
>>>             a2 ~= i;
>>>
>>>         writeln("a1: ", sum(a1));
>>>         writeln("a2: ", sum(a2));
>>>         return 0;
>>>     }
>>>
>>> This throws the error:
>>> dummy.d(11): Error: template std.algorithm.iteration.sum cannot deduce function from argument types !()(uint[3]), candidates are:
>>> /usr/include/dmd/phobos/std/algorithm/iteration.d(3916):
>>>  std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))
>>> /usr/include/dmd/phobos/std/algorithm/iteration.d(3927):
>>>  std.algorithm.iteration.sum(R, E)(R r, E seed) if (isInputRange!R && !isInfinite!R && is(typeof(seed = seed + r.front)))
>>>
>>>
>>> So a dynamic array works just fine. In fact, if I uncomment the line in question the program compiles and outputs the correct value (for a2). Why does "sum" not work on static arrays?
>>>
>>>
>>> Regards
>>
>> So that you do not shoot yourself in the foot too easily. A static array is a value type so it is passed by value to functions. If you pass a 1M array to a function... well, I guesse you don't want to do that.
> 
> Can the template func `sum()` be made to take `ref` of a static array?

There are some functions that deal with static arrays as well as ranges.

I would say no to this request though. If you want a range from a static array, use a slice operation. The places which normally deal with ranges should not automatically use static arrays. We are paying the price for this in lifetime bugs.

> dynamic array and static array cannot be used interchangeably: (sure I'm not talking about array decl / allocation, the user have to take different actions) I'm talking about a simple function call to calc the sum of the array.
> ```
>    sum(static_array[]);   // v.s.
>    sum(dynamic_array);
> ```
> 
> For example, if the user first decl a static array for fast prototyping, and later changed mind to use dynamic array, then s/he need to change the call all over the places.

All correct statements. Static arrays are not the same as dynamic arrays.

> 
> 
> (I hope you are not telling me, every time people should use:
> ```
>    array_func(any_array[]);
> ```
> is the correct D-idiom to use array in a func call)
> 

No, sum accepts a range. A static array is not a range. Simple as that. Just use a slice operator if you want a range from it. It's no different from any other type that is not a range.

For example a std.container.Array is not a range. If you slice it, it gives you a range, which you can then use in algorithms.

-Steve