January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | From the feedback thread: On Wednesday, 6 January 2021 at 17:54:34 UTC, Dukc wrote: > `std.array.staticArray` can already handle most of the problems described, and it does work in betterC - I just tested with LDC 1.20.1 targeting WebAssembly. while there are remaining cases (`auto fun(int[$] = [1,2,3])` isn't easy to represent now), I suspect they are a bit too trivial to justify a new feature. Type inference for parameters with a default argument could be made to work. auto fun(auto a = [1,2,3].staticArray) {return a;} > On to refining the feature if it's accepted anyway. This should work: > ``` > int[$] bar(int[2] arr) // Error: not allowed in functions declarations > { > return arr ~ [3, 4]; > } > ``` > Why? because you can use `auto` as return type. `Type[$]` should IMO work anywhere `auto` does. The inferred return type is int[], and causes an error if the return type is specified as int[4]. > You need to mention that this DIP will break code in this, admittedly rare, case: > ``` > int[] x = something; > int y = something[0 .. staticArrFunc(cast(int[$])[1,2,3])]; > ``` Excellent point, but it isn't just casts, anywhere you use a type (template instantiation) that is within an indexing expression will have this problem. > I wonder if `$` should be allowed inside an expression, like this: > ``` > int[$+2] a = [1,2,3]; //static array of [1,2,3,0,0] > ``` Not worth it, easy to workaround. |
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Wednesday, 6 January 2021 at 17:59:57 UTC, Jacob Carlborg wrote: > There's `staticArray` to solve this issue [1]. It does a slightly different thing. staticArray works with types of literals and values, while the proposed way works with type of the declaration. Now you have to either infer the whole type (`auto`) or not infer anything at all. This proposal would let one to infer the length of a static array without inferring it's type. For example, `short[$] arr = [1,2,3]` isn't easily representable with `staticArray`, as `is(typeof([1,2,3].staticArray) == int[3])`. Whether the issues are different enough to justify a new language feature is another question though. |
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luhrel | On Wednesday, 6 January 2021 at 18:14:42 UTC, Luhrel wrote:
> It works only for the `int` type and above (and other types as structs).
>
> example with short:
> ---
> extern(C) void main()
> {
> import std.array;
> auto a = [0, 1].staticArray!short; // error
> }
Can be fixed (probably with another name):
//import std.array;
import std.stdio;
void main(){
auto a = [1,2,3].staticArray!float;
pragma(msg, typeof(a)); // float[3]
a.writeln();
}
template staticArray(T) {
T[n] staticArray(ulong n) (auto ref T[n] a) {return a;}
}
|
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 6 January 2021 at 18:22:32 UTC, Nick Treleaven wrote: > Type inference for parameters with a default argument could be made to work. > > auto fun(auto a = [1,2,3].staticArray) {return a;} Okay that was a bad example. But see Luhrels answer to Jacob. >> ``` >> int[$] bar(int[2] arr) // Error: not allowed in functions declarations >> { >> return arr ~ [3, 4]; >> } >> ``` > > causes an error if the return type is specified as int[4]. Why? `arr` is static so the compiler should be able to figure that no overflow will ever happen. >> ``` >> int[] x = something; >> int y = something[0 .. staticArrFunc(cast(int[$])[1,2,3])]; >> ``` > > Excellent point, but it isn't just casts, anywhere you use a type (template instantiation) that is within an indexing expression will have this problem. Yeah, this is just the simplest example that came to mind. |
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 6 January 2021 at 18:29:05 UTC, Nick Treleaven wrote:
> Can be fixed (probably with another name):
>
> //import std.array;
Actually template overloading seems to work fine:
template staticArray(T) {
T[n] staticArray(ulong n) (auto ref T[n] a) {return a;}
}
T[n] staticArray(T, ulong n) (auto ref T[n] a) {return a;}
void main(){
auto a = [1,2,3].staticArray!float;
pragma(msg, typeof(a)); // float[3]
a.writeln();
[1,2,3].staticArray.writeln();
}
|
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dukc | On Wednesday, 6 January 2021 at 18:33:54 UTC, Dukc wrote:
>>> ```
>>> int[$] bar(int[2] arr) // Error: not allowed in functions declarations
>>> {
>>> return arr ~ [3, 4];
>>> }
>>> ```
>>
>> causes an error if the return type is specified as int[4].
>
> Why? `arr` is static so the compiler should be able to figure that no overflow will ever happen.
Because:
1. concatenation with a static array is not defined (use `arr[]`).
2. slices do not implicitly convert to a static array.
|
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 6 January 2021 at 18:41:31 UTC, Nick Treleaven wrote: > On Wednesday, 6 January 2021 at 18:33:54 UTC, Dukc wrote: >> Why? `arr` is static so the compiler should be able to figure that no overflow will ever happen. > > Because: > 1. concatenation with a static array is not defined (use `arr[]`). Oh okay. > 2. slices do not implicitly convert to a static array. They do if the length is known at compile time, but `~` does not for some reason propagate the length. This works though: ``` int[4] bar(int[2] arr) { return arr.conc([3, 4]); } T[i+j] conc(T, size_t i, size_t j)(T[i] a, T[j] b) { typeof(return) result; result[0 .. i] = a[]; result[i .. $] = b[]; return result; } ``` |
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 6 January 2021 at 18:34:31 UTC, Nick Treleaven wrote:
> On Wednesday, 6 January 2021 at 18:29:05 UTC, Nick Treleaven wrote:
>> Can be fixed (probably with another name):
>>
>> //import std.array;
>
> Actually template overloading seems to work fine:
>
> template staticArray(T) {
> T[n] staticArray(ulong n) (auto ref T[n] a) {return a;}
> }
>
> T[n] staticArray(T, ulong n) (auto ref T[n] a) {return a;}
>
> void main(){
> auto a = [1,2,3].staticArray!float;
> pragma(msg, typeof(a)); // float[3]
> a.writeln();
> [1,2,3].staticArray.writeln();
> }
What about something like below to handle any user-defined type.
import std.stdio: writeln;
template staticArray(T) {
T[n] staticArray(ulong n) (auto ref T[n] a) {return a;}
T[n] staticArray(U, ulong n) (auto ref U[n] a)
if (!is(T == U))
{
T[n] output;
for(size_t i = 0; i < n; i++) {
output[i] = cast(T) a[i];
}
return output;
}
}
T[n] staticArray(T, ulong n) (auto ref T[n] a) {return a;}
struct Foo {
float x;
T opCast(T)() {
return cast(T) x;
}
}
void main(){
auto a = [1,2,3].staticArray!float;
pragma(msg, typeof(a)); // float[3]
a.writeln();
[1,2,3].staticArray.writeln();
auto b = [1,2,3].staticArray!Foo;
b.writeln();
}
|
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Treleaven | On Wednesday, 6 January 2021 at 18:34:31 UTC, Nick Treleaven wrote:
> On Wednesday, 6 January 2021 at 18:29:05 UTC, Nick Treleaven wrote:
>> Can be fixed (probably with another name):
>>
>> //import std.array;
>
> Actually template overloading seems to work fine:
>
> template staticArray(T) {
> T[n] staticArray(ulong n) (auto ref T[n] a) {return a;}
> }
>
> T[n] staticArray(T, ulong n) (auto ref T[n] a) {return a;}
>
> void main(){
> auto a = [1,2,3].staticArray!float;
> pragma(msg, typeof(a)); // float[3]
> a.writeln();
> [1,2,3].staticArray.writeln();
> }
Still doesn't work with `short`.
|
January 06, 2021 Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Luhrel | On Wednesday, 6 January 2021 at 19:17:46 UTC, Luhrel wrote:
> [snip]
>
> Still doesn't work with `short`.
Pretty sure my version above does.
|
Copyright © 1999-2021 by the D Language Foundation