October 02, 2020
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
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
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
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
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
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
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
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
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
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.