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