Jump to page: 1 27  
Page
Thread overview
September 23
Hi guys,

So, today I wanted to implement handling of typesafe variadic array for type function (alias[] ...).
When writing a test for it I found out that I already did (on the talias_master branch which is different from talias_safe).

So here's the static map as a type function.
This also shows of interplay between templates and type functions.
That should be surprising since type functions are just regular functions that happen to accept types as arguments ;)

---

struct DummyType {} // just a dummy to get the right inference

auto getUDAs(alias T) { return __traits(getAttributes, T); } // needed because that's the shortest thing that'll return alias[]

alias alias_array = typeof(getUDAs(DummyType));

auto static_map_tf(alias F)(alias_array types ...)
{
    typeof(F(DummyType))[] result;
    result.length = types.length;

    foreach(i, t;types)
    {
        result[i] = F(t);
    }

    return result;
}

size_t sizeOf(alias t)
{
    return t.sizeof;
}

alias Int = int;
alias Ushort = ushort; // we need these aliases because the parser won't allow us to call a function with a reserved type identifier.

static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);

---

This code has been working quietly for a while.
So go and download https://github.com/UplinkCoder/dmd/tree/talias_master
Build your own compiler.
And play with type functions.

Cheers,

Stefan
September 23
On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:

> So go and download https://github.com/UplinkCoder/dmd/tree/talias_master
> Build your own compiler.
> And play with type functions.

note. type functions are still an experimental feature, certain actions will cause the interaction with d-runtime to fail for example setting the length of an alias[].
So do expect errors near the end of compilation, I am fixing those as fast as my time allows.

Also the -sktf switch has to be thrown for type functions to be active since they require a semantic rule to be circumvented. The rule being "You can't call a function with types."

That issue is actually a bit tricky to address because of the implementation in dmd.
I can't always know which function a call resolves to before deciding whether to allow types (iff the function is a type function) or not.


September 23
On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:

> That should be surprising since type functions are just regular functions that happen to accept types as arguments ;)

I meant that should _not_ be surprising.
September 23
On Wednesday, 23 September 2020 at 10:51:41 UTC, Stefan Koch wrote:
> On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:
>
>> That should be surprising since type functions are just regular functions that happen to accept types as arguments ;)
>
> I meant that should _not_ be surprising.

Great work. Has Andrei given any advice on how to proceed regarding dip, reviews and acceptance? I presume this will get merged behind a -preview if it gets merged.
September 23
On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:

> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);

Is it possible to use a lambda here?

--
/Jacob Carlborg
September 23
On Wednesday, 23 September 2020 at 12:22:49 UTC, Jacob Carlborg wrote:
> On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:
>
>> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);
>
> Is it possible to use a lambda here?
>
> --
> /Jacob Carlborg

It should be in theory but I advise against it. Mixing lambdas and template alias parameters leads to instantiating different template instances although semantically they're the same.
September 23
On 9/23/20 8:40 AM, Stefan Koch wrote:
> On Wednesday, 23 September 2020 at 12:22:49 UTC, Jacob Carlborg wrote:
>> On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:
>>
>>> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);
>>
>> Is it possible to use a lambda here?
>>
> It should be in theory but I advise against it. Mixing lambdas and template alias parameters leads to instantiating different template instances although semantically they're the same.

what about:

static_map_tf!((alias a) => a.sizeof)(...)

This shouldn't be a template.

-Steve
September 23
On Wednesday, 23 September 2020 at 13:19:34 UTC, Steven Schveighoffer wrote:
> On 9/23/20 8:40 AM, Stefan Koch wrote:
>> On Wednesday, 23 September 2020 at 12:22:49 UTC, Jacob Carlborg wrote:
>>> On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:
>>>
>>>> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);
>>>
>>> Is it possible to use a lambda here?
>>>
>> It should be in theory but I advise against it. Mixing lambdas and template alias parameters leads to instantiating different template instances although semantically they're the same.
>
> what about:
>
> static_map_tf!((alias a) => a.sizeof)(...)
>
> This shouldn't be a template.
>
> -Steve

with:
pragma(msg, (static_map_tf!((alias a) => a.sizeof)(Int, Ushort) == [4, 2]));
pragma(msg, (static_map_tf!((alias a) => a.sizeof)(Int, Ushort) == [4, 2]));

-vtemplates reports:

static_map_tf.d(12): vtemplate: 2 (2 unique) instantiation(s) of template `static_map_tf(alias F)(alias_array types...)` found


with

pragma(msg, (static_map_tf!((alias a) => a.sizeof)(Int, Ushort) == [4, 2]));
pragma(msg, (static_map_tf!((alias a) => a.sizeof)(Int, Ushort) == [4, 2]));
pragma(msg, (static_map_tf!((alias a) => a.sizeof)(Int, Ushort) == [4, 2]));

static_map_tf.d(12): vtemplate: 3 (3 unique) instantiation(s) of template `static_map_tf(alias F)(alias_array types...)` found
September 23
On 9/23/20 9:38 AM, Stefan Koch wrote:
> On Wednesday, 23 September 2020 at 13:19:34 UTC, Steven Schveighoffer wrote:
>> On 9/23/20 8:40 AM, Stefan Koch wrote:
>>> On Wednesday, 23 September 2020 at 12:22:49 UTC, Jacob Carlborg wrote:
>>>> On Wednesday, 23 September 2020 at 09:46:54 UTC, Stefan Koch wrote:
>>>>
>>>>> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);
>>>>
>>>> Is it possible to use a lambda here?
>>>>
>>> It should be in theory but I advise against it. Mixing lambdas and template alias parameters leads to instantiating different template instances although semantically they're the same.
>>
>> what about:
>>
>> static_map_tf!((alias a) => a.sizeof)(...)
>>
>> This shouldn't be a template.
>>

> static_map_tf.d(12): vtemplate: 3 (3 unique) instantiation(s) of template `static_map_tf(alias F)(alias_array types...)` found

Ah ok. You meant the static map template is going to be different because the lambdas are considered different aliases.

That's standard behavior for the current compiler too. I thought you meant that type functions have an extra problem with templates using lambdas.

It makes me wonder -- can the compiler determine identical lambdas and reduce template instantiations? This was one of the problems with moving from string lambdas to actual lambdas.

-Steve
September 23
On Wednesday, 23 September 2020 at 14:05:50 UTC, Steven Schveighoffer wrote:
> On 9/23/20 9:38 AM, Stefan Koch wrote:
>> static_map_tf.d(12): vtemplate: 3 (3 unique) instantiation(s) of template `static_map_tf(alias F)(alias_array types...)` found
>
> Ah ok. You meant the static map template is going to be different because the lambdas are considered different aliases.
>
> That's standard behavior for the current compiler too. I thought you meant that type functions have an extra problem with templates using lambdas.
>
> It makes me wonder -- can the compiler determine identical lambdas and reduce template instantiations? This was one of the problems with moving from string lambdas to actual lambdas.
>
> -Steve

There was some limited support for lambda comparison added in 2.079:
https://dlang.org/changelog/2.079.0.html#lambdacomp
« First   ‹ Prev
1 2 3 4 5 6 7