October 10, 2020 Why does sum not work in static arrays? | ||||
---|---|---|---|---|
| ||||
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 Re: Why does sum not work in static arrays? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mw | 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 |
Copyright © 1999-2021 by the D Language Foundation