digitalmars.D - Type functions with std.algorithm
- Stefan Koch (18/18) Oct 10 2020 The code below here works with the current talias_master branch!
- Petar Kirov [ZombineDev] (7/25) Oct 10 2020 Nice!
- Stefan Koch (11/42) Oct 11 2020 Indeed there is an issue with std.array.array.
- Stefan Koch (42/52) Oct 11 2020 I found out what happens.
- Stefan Koch (19/22) Oct 11 2020 Turns out that is not the case now array fails with:
- Stefan Koch (18/30) Oct 11 2020 Wow this is so strange ...
- Timon Gehr (10/22) Oct 11 2020 Probably the compiler thinks that you are calling the function with an
- Stefan Koch (3/27) Oct 12 2020 Thanks for the pointer.
The code below here works with the current talias_master branch! alias type = __type; type[] makeTypeArray(type[] types ...) { return types; } import std.algorithm; enum type[] types = makeTypeArray(int, uint, long, ulong); enum size4 = types.filter!((type a) { return a.sizeof == 4; } ); pragma(msg, () { type[] result = []; foreach(t;size4) { result ~= t; } return result; }().tupleof); // outputs: tuple((int), (uint))
Oct 10 2020
On Sunday, 11 October 2020 at 00:46:37 UTC, Stefan Koch wrote:The code below here works with the current talias_master branch! alias type = __type; type[] makeTypeArray(type[] types ...) { return types; } import std.algorithm; enum type[] types = makeTypeArray(int, uint, long, ulong); enum size4 = types.filter!((type a) { return a.sizeof == 4; } ); pragma(msg, () { type[] result = []; foreach(t;size4) { result ~= t; } return result; }().tupleof); // outputs: tuple((int), (uint))Nice! Is there an issue with `std.array.array`, or you just prefer manually converting the range to an array? Btw, dmd can evaluate ranges at compile-time (e.g. in static foreach), so .tupleof could potentially also do that (convert both ranges and arrays of types to a tuples).
Oct 10 2020
On Sunday, 11 October 2020 at 06:22:26 UTC, Petar Kirov [ZombineDev] wrote:On Sunday, 11 October 2020 at 00:46:37 UTC, Stefan Koch wrote:Indeed there is an issue with std.array.array. It seems to want to convert __type[] into void[] or something. Which makes some template constraint fail. __type[] to void[] cannot be implemented because strictly speaking the __type[] doesn't hold any data. I think this can be fixed, by pretending there to be data, however than I loose other nice properties such as __type.sizeof == 0; So I will likely need to find a different way.The code below here works with the current talias_master branch! alias type = __type; type[] makeTypeArray(type[] types ...) { return types; } import std.algorithm; enum type[] types = makeTypeArray(int, uint, long, ulong); enum size4 = types.filter!((type a) { return a.sizeof == 4; } ); pragma(msg, () { type[] result = []; foreach(t;size4) { result ~= t; } return result; }().tupleof); // outputs: tuple((int), (uint))Nice! Is there an issue with `std.array.array`, or you just prefer manually converting the range to an array? Btw, dmd can evaluate ranges at compile-time (e.g. in static foreach), so .tupleof could potentially also do that (convert both ranges and arrays of types to a tuples).
Oct 11 2020
On Sunday, 11 October 2020 at 10:19:56 UTC, Stefan Koch wrote:On Sunday, 11 October 2020 at 06:22:26 UTC, Petar Kirov [ZombineDev] wrote:I found out what happens. This is funky, so fasten your seatbelts :) Here is the reproducible case: --- property ref inout(T) front(T)(return scope inout(T)[] a) safe pure nothrow nogc // if (!isAutodecodableString!(T[]) && !is(T[] == void[])) commented out to avoid deps { assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof); return a[0]; } template ElementType(R) { pragma(msg, "R: ", R, ", R.init: ", R.init, ", typeof(R.init.front): ", typeof(R.init.front) ); static if (is(typeof(R.init.front.init) T)) alias ElementType = T; else alias ElementType = void; } pragma(msg, is(ElementType!(__type[]) == void)); pragma(msg, is(ElementType!(int[]) == void)); --- Which prints: R: __type[], R.init: null, typeof(R.init.front): __type true R: int[], R.init: null, typeof(R.init.front): int false That tells us that the front wrapper works correctly. range __type[] correctly returns a __type; so R.init.front is a variable of type __type which makes R.init.front.init be the type __emptyType. the bug is that because __emptyType is a type typeof(__emptyType) returns void, which is consistent with how the language has treated types before type functions (they didn't have a type). So all I have to do is to teach that the type of any type is __type. And then everything will work!Is there an issue with `std.array.array`, or you just prefer manually converting the range to an array? Btw, dmd can evaluate ranges at compile-time (e.g. in static foreach), so .tupleof could potentially also do that (convert both ranges and arrays of types to a tuples).Indeed there is an issue with std.array.array. ...
Oct 11 2020
On Sunday, 11 October 2020 at 13:49:20 UTC, Stefan Koch wrote:So all I have to do is to teach that the type of any type is __type. And then everything will work!Turns out that is not the case now array fails with: phobos/std/conv.d(4529): Error: constructor std.conv.emplaceRef!(__type, __type, __type).emplaceRef.S.this(ref __type _param_0) is not callable using argument types ((__type)) I believe this is an implicit conversion problem ... Seriously how complicated is phobos ... all you need to do is a foreach loop. What does std.conv.emplaceRef have to do with it? remember the code I want to compile is: --- import std.algorithm; import std.range; enum type[] types = makeTypeArray(int, uint, long, ulong); enum size4 = types.filter!((type a) { return a.sizeof == 4; } ).array; --- and now I worrying about std.conv.emplaceRef ?
Oct 11 2020
On Sunday, 11 October 2020 at 15:46:19 UTC, Stefan Koch wrote:On Sunday, 11 October 2020 at 13:49:20 UTC, Stefan Koch wrote:Wow this is so strange ... lvalue to ref conversion works just fine. The code below works ... but what else could be going on here? --- alias type = __type; type ret(type x) { alias y = x; y = passthrough(y); return y; } type passthrough(ref type y) { return y; } pragma(msg, ret(int)); // prints int ---So all I have to do is to teach that the type of any type is __type. And then everything will work!Turns out that is not the case now array fails with: phobos/std/conv.d(4529): Error: constructor std.conv.emplaceRef!(__type, __type, __type).emplaceRef.S.this(ref __type _param_0) is not callable using argument types ((__type)) I believe this is an implicit conversion problem ...
Oct 11 2020
On 11.10.20 17:46, Stefan Koch wrote:On Sunday, 11 October 2020 at 13:49:20 UTC, Stefan Koch wrote:Probably the compiler thinks that you are calling the function with an rvalue: --- void foo(ref int){} void main(){ foo(2); } --- test.d(2): Error: function `test.foo(ref int _param_0)` is not callable using argument types `(int)` ---So all I have to do is to teach that the type of any type is __type. And then everything will work!Turns out that is not the case now array fails with: phobos/std/conv.d(4529): Error: constructor std.conv.emplaceRef!(__type, __type, __type).emplaceRef.S.this(ref __type _param_0) is not callable using argument types ((__type)) I believe this is an implicit conversion problem ...
Oct 11 2020
On Sunday, 11 October 2020 at 16:53:25 UTC, Timon Gehr wrote:On 11.10.20 17:46, Stefan Koch wrote:Thanks for the pointer. I hope to fix this bug soon.On Sunday, 11 October 2020 at 13:49:20 UTC, Stefan Koch wrote:Probably the compiler thinks that you are calling the function with an rvalue: --- void foo(ref int){} void main(){ foo(2); } --- test.d(2): Error: function `test.foo(ref int _param_0)` is not callable using argument types `(int)` ---So all I have to do is to teach that the type of any type is __type. And then everything will work!Turns out that is not the case now array fails with: phobos/std/conv.d(4529): Error: constructor std.conv.emplaceRef!(__type, __type, __type).emplaceRef.S.this(ref __type _param_0) is not callable using argument types ((__type)) I believe this is an implicit conversion problem ...
Oct 12 2020