Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 28, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Attachments:
| 2013/5/28 Manu <turkeyman@gmail.com>
> So I've run into an expression I need to be able to implement std.simd properly for GDC/LDC.
>
> Doesn't work:
> @attribute("target", T) void func(string T)(...);
>
> In this case, currently, the UDA can't receive the template arg that was given to the function.
>
> I require that attributes on templates be able to make use of the template args, since the template arg given may affect the attribute in some circumstances.
>
This code works.
string attribute(string, string s) { return s; }
//@attribute("target", T) void func(string T)() {}
template func(string T)
{
@attribute("target", T) void func() {}
}
void main()
{
alias f1 = func!"a";
alias f2 = func!"b";
pragma(msg, __traits(getAttributes, f1)); // "a"
pragma(msg, __traits(getAttributes, f2)); // "b"
f1();
f2();
}
Kenji Hara
|
May 28, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Attachments:
| Indeed it does.
It's a bit obtuse though having to wrap my function up in an outer template
just to scope the template arg correctly.
Do you think it's reasonable that an attribute should be scoped such that
it can see the template args of the declaration it's bound to?
It kinda makes sense, an attribute is intrinsically connected to the
declaration, so it should be able to access any template args given...
On 28 May 2013 23:51, Kenji Hara <k.hara.pg@gmail.com> wrote:
> 2013/5/28 Manu <turkeyman@gmail.com>
>
>> So I've run into an expression I need to be able to implement std.simd properly for GDC/LDC.
>>
>> Doesn't work:
>> @attribute("target", T) void func(string T)(...);
>>
>> In this case, currently, the UDA can't receive the template arg that was given to the function.
>>
>> I require that attributes on templates be able to make use of the template args, since the template arg given may affect the attribute in some circumstances.
>>
>
> This code works.
>
> string attribute(string, string s) { return s; }
>
> //@attribute("target", T) void func(string T)() {}
> template func(string T)
> {
> @attribute("target", T) void func() {}
> }
>
> void main()
> {
> alias f1 = func!"a";
> alias f2 = func!"b";
> pragma(msg, __traits(getAttributes, f1)); // "a"
> pragma(msg, __traits(getAttributes, f2)); // "b"
> f1();
> f2();
> }
>
> Kenji Hara
>
|
May 28, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Attachments:
| It looks reasonable, but in general case it would introduce not trivial semantic issue.
Based on the current D language spec, prefix attribute is just rewritten to blocked attribute.
@attribute("target", T) void func(string T)() {}
to:
@attribute("target", T) {
void func(string T)() {}
}
And block attribute can contain other declarations.
@attribute("target", T) {
enum str = T.stringof;
void func(string T)() {}
}
Well, if the enhancement is implemented, T would be deduced by the each call of template function foo. Then the enum value would become undeterministic.
I think it is not implementable.
Kenji Hara
2013/5/28 Manu <turkeyman@gmail.com>
> Indeed it does.
> It's a bit obtuse though having to wrap my function up in an outer
> template just to scope the template arg correctly.
>
> Do you think it's reasonable that an attribute should be scoped such that
> it can see the template args of the declaration it's bound to?
> It kinda makes sense, an attribute is intrinsically connected to the
> declaration, so it should be able to access any template args given...
>
>
> On 28 May 2013 23:51, Kenji Hara <k.hara.pg@gmail.com> wrote:
>
>> 2013/5/28 Manu <turkeyman@gmail.com>
>>
>>> So I've run into an expression I need to be able to implement std.simd properly for GDC/LDC.
>>>
>>> Doesn't work:
>>> @attribute("target", T) void func(string T)(...);
>>>
>>> In this case, currently, the UDA can't receive the template arg that was given to the function.
>>>
>>> I require that attributes on templates be able to make use of the template args, since the template arg given may affect the attribute in some circumstances.
>>>
>>
>> This code works.
>>
>> string attribute(string, string s) { return s; }
>>
>> //@attribute("target", T) void func(string T)() {}
>> template func(string T)
>> {
>> @attribute("target", T) void func() {}
>> }
>>
>> void main()
>> {
>> alias f1 = func!"a";
>> alias f2 = func!"b";
>> pragma(msg, __traits(getAttributes, f1)); // "a"
>> pragma(msg, __traits(getAttributes, f2)); // "b"
>> f1();
>> f2();
>> }
>>
>> Kenji Hara
>>
>
>
|
May 28, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | Am Tue, 28 May 2013 22:51:29 +0900 schrieb Kenji Hara <k.hara.pg@gmail.com>: > 2013/5/28 Manu <turkeyman@gmail.com> > > > This code works. > Interesting. I tried that as well but used writeln to print the output: writeln(__traits(getAttributes, func!"a")); //Fails enum result = __traits(getAttributes, func!"a"); writeln(result); //works Is this a known bug? |
May 29, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Attachments:
| On 29 May 2013 01:45, Kenji Hara <k.hara.pg@gmail.com> wrote: > It looks reasonable, but in general case it would introduce not trivial semantic issue. > > Based on the current D language spec, prefix attribute is just rewritten to blocked attribute. > > @attribute("target", T) void func(string T)() {} > > to: > @attribute("target", T) { > void func(string T)() {} > } > > And block attribute can contain other declarations. > > @attribute("target", T) { > > enum str = T.stringof; > > void func(string T)() {} > } > > Well, if the enhancement is implemented, T would be deduced by the each call of template function foo. Then the enum value would become undeterministic. > > I think it is not implementable. > Well, until now, the lowering of an attribute to a scoped attribute would have always worked seamlessly, since no hard attributes ever received arguments. I'd suggest that it may no longer be reasonable behaviour to lower an attribute to a scoped attribute. @attribute("target", T) void func(string T)() {} @attribute("target", T) { ...stuff... void func(string T)() {} ...stuff... } The 2 cases are quite distinct. In the first, it looks very much like the the attribute is attributing the declaration (it really is PART of the declaration), and as such, should have access to any arguments supplied to the declaration. In the second case, it's quite clear that there is an outer scope. Any reasonably programmer will expect that parameters to an inner declaration will not be available in the outer scope. The issue seems to be an implementation detail, which was based on a premise that's no longer strictly true. Kenji Hara > > > 2013/5/28 Manu <turkeyman@gmail.com> > >> Indeed it does. >> It's a bit obtuse though having to wrap my function up in an outer >> template just to scope the template arg correctly. >> >> Do you think it's reasonable that an attribute should be scoped such that >> it can see the template args of the declaration it's bound to? >> It kinda makes sense, an attribute is intrinsically connected to the >> declaration, so it should be able to access any template args given... >> >> >> On 28 May 2013 23:51, Kenji Hara <k.hara.pg@gmail.com> wrote: >> >>> 2013/5/28 Manu <turkeyman@gmail.com> >>> >>>> So I've run into an expression I need to be able to implement std.simd properly for GDC/LDC. >>>> >>>> Doesn't work: >>>> @attribute("target", T) void func(string T)(...); >>>> >>>> In this case, currently, the UDA can't receive the template arg that was given to the function. >>>> >>>> I require that attributes on templates be able to make use of the template args, since the template arg given may affect the attribute in some circumstances. >>>> >>> >>> This code works. >>> >>> string attribute(string, string s) { return s; } >>> >>> //@attribute("target", T) void func(string T)() {} >>> template func(string T) >>> { >>> @attribute("target", T) void func() {} >>> } >>> >>> void main() >>> { >>> alias f1 = func!"a"; >>> alias f2 = func!"b"; >>> pragma(msg, __traits(getAttributes, f1)); // "a" >>> pragma(msg, __traits(getAttributes, f2)); // "b" >>> f1(); >>> f2(); >>> } >>> >>> Kenji Hara >>> >> >> > |
May 31, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | On 05/28/2013 05:45 PM, Kenji Hara wrote: > It looks reasonable, but in general case it would introduce not trivial > semantic issue. > > Based on the current D language spec, prefix attribute is just rewritten > to blocked attribute. > > @attribute("target", T) void func(string T)() {} > > to: > @attribute("target", T) { > void func(string T)() {} > } > It is my understanding as well, but where is this actually specified? > And block attribute can contain other declarations. > > @attribute("target", T) { > > enum str = T.stringof; > > void func(string T)() {} > } > > Well, if the enhancement is implemented, T would be deduced by the each > call of template function foo. Then the enum value would become > undeterministic. > > I think it is not implementable. > ... This does not follow. @attribute("target", T) void func(string T)() {} would simply need to be treated like: template func(string T){ @attribute("target", T) void func() {} } (The same would then be done for other attributes.) I think it makes a difference only for UDA's and pragmas. |
May 31, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr Attachments:
| On 31 May 2013 20:47, Timon Gehr <timon.gehr@gmx.ch> wrote:
> On 05/28/2013 05:45 PM, Kenji Hara wrote:
>
>> It looks reasonable, but in general case it would introduce not trivial semantic issue.
>>
>> Based on the current D language spec, prefix attribute is just rewritten to blocked attribute.
>>
>> @attribute("target", T) void func(string T)() {}
>>
>> to:
>> @attribute("target", T) {
>> void func(string T)() {}
>> }
>>
>>
> It is my understanding as well, but where is this actually specified?
>
> And block attribute can contain other declarations.
>>
>> @attribute("target", T) {
>>
>> enum str = T.stringof;
>>
>> void func(string T)() {}
>> }
>>
>> Well, if the enhancement is implemented, T would be deduced by the each call of template function foo. Then the enum value would become undeterministic.
>>
>> I think it is not implementable.
>> ...
>>
>
>
> This does not follow.
>
> @attribute("target", T) void func(string T)() {}
>
> would simply need to be treated like:
>
>
> template func(string T){
> @attribute("target", T) void func() {}
> }
>
> (The same would then be done for other attributes.)
>
> I think it makes a difference only for UDA's and pragmas.
>
Or fully expanded:
template func(string T) {
@attribute("target", T) {
void func() { }
}
}
This seems to fix the existing semantics rather nicely.
|
May 31, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Attachments:
| * fix = fit
On 31 May 2013 20:56, Manu <turkeyman@gmail.com> wrote:
> On 31 May 2013 20:47, Timon Gehr <timon.gehr@gmx.ch> wrote:
>
>> On 05/28/2013 05:45 PM, Kenji Hara wrote:
>>
>>> It looks reasonable, but in general case it would introduce not trivial semantic issue.
>>>
>>> Based on the current D language spec, prefix attribute is just rewritten to blocked attribute.
>>>
>>> @attribute("target", T) void func(string T)() {}
>>>
>>> to:
>>> @attribute("target", T) {
>>> void func(string T)() {}
>>> }
>>>
>>>
>> It is my understanding as well, but where is this actually specified?
>>
>> And block attribute can contain other declarations.
>>>
>>> @attribute("target", T) {
>>>
>>> enum str = T.stringof;
>>>
>>> void func(string T)() {}
>>> }
>>>
>>> Well, if the enhancement is implemented, T would be deduced by the each call of template function foo. Then the enum value would become undeterministic.
>>>
>>> I think it is not implementable.
>>> ...
>>>
>>
>>
>> This does not follow.
>>
>> @attribute("target", T) void func(string T)() {}
>>
>> would simply need to be treated like:
>>
>>
>> template func(string T){
>> @attribute("target", T) void func() {}
>> }
>>
>> (The same would then be done for other attributes.)
>>
>> I think it makes a difference only for UDA's and pragmas.
>>
>
> Or fully expanded:
>
> template func(string T) {
> @attribute("target", T) {
> void func() { }
> }
> }
>
> This seems to fix the existing semantics rather nicely.
>
|
May 31, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Fri, 31 May 2013 06:47:07 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:
> @attribute("target", T) void func(string T)() {}
>
> would simply need to be treated like:
>
> template func(string T){
> @attribute("target", T) void func() {}
> }
In fact, today's current semantics suggest this is exactly what happens:
import std.stdio;
@("a") void func(T)(T t) {}
void main()
{
writefln("func attributes: %s", [__traits(getAttributes, func)]);
writefln("func!int attributes: %s", [__traits(getAttributes, func!int)]);
}
Output:
func attributes: []
func!int attributes: ["a"]
If the attributes applied only to the template symbol, then you would think func would have the attribute a.
Plus, the idea that you must actually instantiate the template to get an attribute to apply REALLY suggests the attribute should be aware of the template parameters.
-Steve
|
June 01, 2013 Re: Template args to UDA's | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 05/31/2013 04:23 PM, Steven Schveighoffer wrote: > On Fri, 31 May 2013 06:47:07 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote: > >> @attribute("target", T) void func(string T)() {} >> >> would simply need to be treated like: >> >> template func(string T){ >> @attribute("target", T) void func() {} >> } > > In fact, today's current semantics suggest this is exactly what happens: > It is not what happens (otherwise Manu's initial code would work), but you obviously have a point. > import std.stdio; > > @("a") void func(T)(T t) {} > > void main() > { > writefln("func attributes: %s", [__traits(getAttributes, func)]); > writefln("func!int attributes: %s", [__traits(getAttributes, > func!int)]); > } > > Output: > > func attributes: [] > func!int attributes: ["a"] > > If the attributes applied only to the template symbol, then you would > think func would have the attribute a. > > Plus, the idea that you must actually instantiate the template to get an > attribute to apply REALLY suggests the attribute should be aware of the > template parameters. > > -Steve Agreed. |
Copyright © 1999-2021 by the D Language Foundation