October 02, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 02.10.20 06:04, Walter Bright wrote:
> On 10/1/2020 5:41 AM, Timon Gehr wrote:
>> On 01.10.20 10:59, Walter Bright wrote:
>>> On 10/1/2020 12:51 AM, Timon Gehr wrote:
>>>> Maybe this is related to what you mean?
>>>>
>>>> type t = readln().strip()=="int"?int:double;
>>>> auto f = (t x)=>x;
>>>
>>>
>>> As D is a statically typed language, I don't see how that can ever work.
>>
>> The example is easy to type check statically. In terms of ABI, you just have to make sure that `f` can find the context pointer without already knowing the value of `t`, then it can reconstruct everything it needs to know.
>
> I think you described D's "class" type. To make it work with int and double, you'd need to "box" them with a class. Like Java.
No, you'd still pass them by value in appropriate registers or on the stack, but you only figure out at run time where the argument is actually located.
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 1 October 2020 at 02:49:43 UTC, Stefan Koch wrote: > On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote: >> On 29.09.20 01:37, Stefan Koch wrote: >>> [...] >> >> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification: >> >> type t = int; >> auto f = (t x)=>x; > > Yes I do understand that. > I was wondering about practical usecases. import std.algorithm: filter, equal; type[] types = [int, uint, long, ulong]; auto size4 = types.filter!(a => a.sizeof == 4); assert(equal(size4, [int, uint])); No more std.meta.Filter. > As far as I an aware, if I made the leap to first class types, that would make all usage of them into static polymorphism. (equivalent to templates) > And with that all the issues come back. I can't see how that's the case. |
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Saturday, 26 September 2020 at 16:18:27 UTC, Andrei Alexandrescu wrote:
> I'll start with the punchline: at the link below you'll find an alpha-quality reimplementation of std.meta in an iterative manner:
>
> https://gist.github.com/andralex/6212ebf2b38c59c96cf66d0009336318
>
> It's the bulk of std.meta - I stopped when it became obvious doing more is just more of the same. Compiles and runs with dmd 2.092 and probably others.
>
> The implementation uses throughout a reification/dereification approach. To reify a type or alias means to convert it into a value. To dereify a value means to turn it back into the type or alias it originated from.
>
> The algorithms follow the following pattern consistently:
>
> 1. Reify the compile-time parameters into values
> 2. Carry processing on these values with the usual algorithms
> 3. If needed, dereify back the results into compile-time parameters
>
> Not all artifacts need step 3. For example, allSatisfy returns a bool, not a type.
>
> For the most part implementation has been a healthy gallop that took a couple of hours yesterday and a couple of hours today. Its weakest point is it uses .stringof for types, which has issues with local types. Hopefully https://github.com/dlang/dmd/pull/11797 could help with that.
>
> Most implementations are a few lines long because they get to leverage algorithms as implemented in std. Here's a typical one:
>
> alias MostDerived(Args...) = dereify!({
> auto ids = reify!Args;
> sort!((a, b) => is(dereify!a : dereify!b))(ids);
> return ids;
> }());
>
> To sort an AliasSeq with most derived elements first, create a lambda to reify the arguments into values, sort the values, and return the sorted result. Then call the lambda and use dereify against its result. And that is IT.
>
> Commments and ideas for improvements are welcome.
1. This is awesome.
2. I agree with everything said about keeping the core language simple and lowering to fundamental constructs. I agree with that in general, and it's a lot easier to agree with it in the context of D given that it's a large language already.
Lisp got mentioned in this thread as if it's some kind of failure, and for the life for me I have no idea why.
Users: dmd has too many bugs!
Also users: please add my bugs, err, feature!
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Thursday, 8 October 2020 at 09:44:33 UTC, Atila Neves wrote:
> On Thursday, 1 October 2020 at 02:49:43 UTC, Stefan Koch wrote:
>> On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
>>> On 29.09.20 01:37, Stefan Koch wrote:
>>>> [...]
>>>
>>> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>>>
>>> type t = int;
>>> auto f = (t x)=>x;
>>
>> Yes I do understand that.
>> I was wondering about practical usecases.
>
> import std.algorithm: filter, equal;
>
> type[] types = [int, uint, long, ulong];
> auto size4 = types.filter!(a => a.sizeof == 4);
> assert(equal(size4, [int, uint]));
>
> No more std.meta.Filter.
>
>> As far as I an aware, if I made the leap to first class types, that would make all usage of them into static polymorphism. (equivalent to templates)
>> And with that all the issues come back.
>
> I can't see how that's the case.
What you just described is what type functions do.
The point that with first class type you could do also this:
// cat type_list.txt: 'int, uint, long, ulong';
auto type_txt = readText("type_list.txt");
type[] types = type_txt.parseTypes()
auto size4 = types.filter!(a => a.sizeof == 4);
assert(equal(size4, [int, uint]));
type[0] myVar1;
type[1] myVar2;
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On Thursday, 8 October 2020 at 09:51:28 UTC, Stefan Koch wrote:
> On Thursday, 8 October 2020 at 09:44:33 UTC, Atila Neves wrote:
>> On Thursday, 1 October 2020 at 02:49:43 UTC, Stefan Koch wrote:
>>> [...]
>>
>> import std.algorithm: filter, equal;
>>
>> type[] types = [int, uint, long, ulong];
>> auto size4 = types.filter!(a => a.sizeof == 4);
>> assert(equal(size4, [int, uint]));
>>
>> No more std.meta.Filter.
>>
>>> [...]
>>
>> I can't see how that's the case.
>
> What you just described is what type functions do.
> The point that with first class type you could do also this:
>
> // cat type_list.txt: 'int, uint, long, ulong';
> auto type_txt = readText("type_list.txt");
> type[] types = type_txt.parseTypes()
> auto size4 = types.filter!(a => a.sizeof == 4);
> assert(equal(size4, [int, uint]));
> type[0] myVar1;
> type[1] myVar2;
There's no IO at compile-time.
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Thursday, 8 October 2020 at 10:05:10 UTC, Atila Neves wrote:
> On Thursday, 8 October 2020 at 09:51:28 UTC, Stefan Koch wrote:
>> On Thursday, 8 October 2020 at 09:44:33 UTC, Atila Neves wrote:
>>> [...]
>>
>> What you just described is what type functions do.
>> The point that with first class type you could do also this:
>>
>> // cat type_list.txt: 'int, uint, long, ulong';
>> auto type_txt = readText("type_list.txt");
>> type[] types = type_txt.parseTypes()
>> auto size4 = types.filter!(a => a.sizeof == 4);
>> assert(equal(size4, [int, uint]));
>> type[0] myVar1;
>> type[1] myVar2;
>
> There's no IO at compile-time.
Exactly!
first class type can be determined at runtime!
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Thursday, 8 October 2020 at 09:44:33 UTC, Atila Neves wrote:
> On Thursday, 1 October 2020 at 02:49:43 UTC, Stefan Koch wrote:
>> On Wednesday, 30 September 2020 at 23:17:27 UTC, Timon Gehr wrote:
>>> On 29.09.20 01:37, Stefan Koch wrote:
>>>> [...]
>>>
>>> It's not a first-class type if you can't declare a variable of that type. If this does not work, it's not first-class, it's syntax sugar for reification:
>>>
>>> type t = int;
>>> auto f = (t x)=>x;
>>
>> Yes I do understand that.
>> I was wondering about practical usecases.
>
> import std.algorithm: filter, equal;
>
> type[] types = [int, uint, long, ulong];
> auto size4 = types.filter!(a => a.sizeof == 4);
> assert(equal(size4, [int, uint]));
>
> No more std.meta.Filter.
>
>> As far as I an aware, if I made the leap to first class types, that would make all usage of them into static polymorphism. (equivalent to templates)
>> And with that all the issues come back.
>
> I can't see how that's the case.
This is the correct type function way of doing it:
enum type[] types = makeTypeArray(int, uint, long, ulong);
enum type[] size4 = types.filter!((type a) => a.sizeof == 4);
static assert(equal!((type a, type b) => a is b) (size4, makeTypeArray(int, uint)));
Currently type[] fails is isInputRange though and therefore the phobos filter won't instantiate.
I am debugging this.
|
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Thursday, 8 October 2020 at 09:51:15 UTC, Atila Neves wrote: > > 1. This is awesome. > 2. I agree with everything said about keeping the core language simple and lowering to fundamental constructs. I agree with that in general, and it's a lot easier to agree with it in the context of D given that it's a large language already. > > Lisp got mentioned in this thread as if it's some kind of failure, and for the life for me I have no idea why. > > Users: dmd has too many bugs! > Also users: please add my bugs, err, feature! --- alias MostDerived(Args...) = dereify!({ > auto ids = reify!Args; > sort!((a, b) => is(dereify!a : dereify!b))(ids); > return ids; > }()); --- Note that the example I re-posted above doesn't actually work. Because of polymorphism. |
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | On 10/8/20 7:06 AM, Stefan Koch wrote: > On Thursday, 8 October 2020 at 09:51:15 UTC, Atila Neves wrote: >> >> 1. This is awesome. >> 2. I agree with everything said about keeping the core language simple and lowering to fundamental constructs. I agree with that in general, and it's a lot easier to agree with it in the context of D given that it's a large language already. >> >> Lisp got mentioned in this thread as if it's some kind of failure, and for the life for me I have no idea why. >> >> Users: dmd has too many bugs! >> Also users: please add my bugs, err, feature! > > --- > alias MostDerived(Args...) = dereify!({ >> auto ids = reify!Args; >> sort!((a, b) => is(dereify!a : dereify!b))(ids); >> return ids; >> }()); > --- > > Note that the example I re-posted above doesn't actually work. > Because of polymorphism. The following works: alias DerivedToFront(Args...) = dereify!({ auto ids = reifyArray!Args; ids.sort; return ids; }()); https://gist.github.com/andralex/0d85df38be2d9ffbe89cf1fb51c44213 |
October 08, 2020 Re: Reimplementing the bulk of std.meta iteratively | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 8 October 2020 at 12:05:22 UTC, Andrei Alexandrescu wrote:
>
>
> The following works:
>
> alias DerivedToFront(Args...) = dereify!({
> auto ids = reifyArray!Args;
> ids.sort;
> return ids;
> }());
>
> https://gist.github.com/andralex/0d85df38be2d9ffbe89cf1fb51c44213
Only with the ID struct that defines the op-compare.
Which is significantly more complicated that the custom sort predicate.
And also more inflexible.
|
Copyright © 1999-2021 by the D Language Foundation