September 23, 2020 static map as a type function | ||||
|---|---|---|---|---|
| ||||
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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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, 2020 Re: static map as a type function | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply