October 08, 2020
Hi there,

Atlia just wrote of what he thinks first class type should allow him to do:
https://forum.dlang.org/post/uscehdzicfluyjyspocm@forum.dlang.org

Luckily he does not actually require first class types for this.
type functions do exactly what he wants.

he 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]));
---

that of course won't compile because the assert has to be a static assert.
also the array literal of types is currently unsupported.
and for some reason isInputRange fails to instantiate for `alias[]`
which means we can't use phobos directly.

So we have to implement phobos filter and phobos equal ourselves.
Similarly `==` is not defined for types right now ... and I don't see how it makes sense,
given we have the is expression ... which means we have to pass a predicate to equals.
Other than that, his code runs with type functions right now!

---
alias type = alias;

type[] makeTypeArray(type[] types ...)
{
    return types;
}


// has to be written because right now, alias.init is the errorType;
// which means that is() and __traits(compiles) may fail if alias.init is used.

auto filter(alias pred, E)(E array) if (is(typeof(E.init[0]) == alias))
{
    E result;
    size_t len;
    result.length = array.length;
    foreach(e;array)
    {
        if (pred(e))
        {
            result[len++] = e;
        }
    }
    return result[0 .. len];
}

bool equal(alias pred, E)(E array1, E array2) if (is(typeof(E.init[0]) == alias))
{
    if (array1.length != array2.length)
        return false;

    immutable len = array1.length;

    foreach(i; 0 .. len)
    {
        if (!pred(array1[i], array2[i]))
        {
            return false;
        }
    }
    return true;
}

enum type[] types = makeTypeArray(int, uint, long, ulong);
pragma(msg, makeTypeArray(int, uint, long, ulong).tupleof);
enum type[] size4 = types.filter!((type a) => a.sizeof == 4);
static assert(equal!((type a, type b) => is(a == b)) (size4, makeTypeArray(int, uint)));
pragma(msg, size4); // unsurprisingly prints [(int), (uint)]

---

Cheers,
Stefan
October 08, 2020
On Thursday, 8 October 2020 at 10:59:23 UTC, Stefan Koch wrote:
> Hi there,
>
> Atlia just wrote of what he thinks first class type should allow him to do:
> https://forum.dlang.org/post/uscehdzicfluyjyspocm@forum.dlang.org
>
> Luckily he does not actually require first class types for this.
> type functions do exactly what he wants.
>
> he 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]));

Note this code should actually compile with type functions in theory.
It's only implementation constraints imposed by the structure of DMD, and straight bugs in the type-function implementation that prevent this from working.

right now DMD is not aware that alias is the common type of all types and therefore will be unable to type the array literal.
That should be fixed in a couple weeks, similarly alias.init will be amended to be the __emptyType.
Which is also a basic type that is not a type, but is not an error.


I think after that the using std.algorithm with a type function should actually work.