November 06, 2012
On Tuesday, 6 November 2012 at 13:55:49 UTC, Rory McGuire wrote:
> You can put the attribute on the function.

Yeah, but that's an awfully roundabout way to add an attribute to the parameter...

if it went on func params:
void foo([Hint("this does something")] string something) {}

otherwise we'd have to do something like

[ParamHint("something", "this does something")] void foo(string something) {}


Which isn't really ahead from the old hack of

enum attr_foo_someting = Hint("");

and has similar problems in matching names. It's a little better but not as good as it could be.
November 06, 2012
On Tuesday, 6 November 2012 at 14:05:46 UTC, Adam D. Ruppe wrote:
> On Tuesday, 6 November 2012 at 13:55:49 UTC, Rory McGuire wrote:
>> You can put the attribute on the function.
>
> Yeah, but that's an awfully roundabout way to add an attribute to the parameter...
>
> if it went on func params:
> void foo([Hint("this does something")] string something) {}
>
> otherwise we'd have to do something like
>
> [ParamHint("something", "this does something")] void foo(string something) {}
>
>
> Which isn't really ahead from the old hack of
>
> enum attr_foo_someting = Hint("");
>
> and has similar problems in matching names. It's a little better but not as good as it could be.

What if the data in the attribute needs to be specific to the symbol on which the attribute is set on? Can you query the symbol from inside the attribute?
What if the attribute needs to change the symbol being defined?
For instance (using commonly desired syntax):

@flags enum A { ... }

the "flags" attribute would replace the declaraction of A with another enum declaration with the same name and same members, but with replaced initialization and would static assert(false, "flags enum can't have initializers") if any initializers are given.

The existing "[data] declaration" is one thing. It adds compile-time data to symbols, which is very very important, but it's not the only thing that is needed. What I described above is not quite an attribute, but an annotation. The semantics of attributes as Walter made them is perfect. The annotation should be  defined like so:

template myAnnotation(alias symbol, annot_args...)
{
    // ...
    ["myAnnoration adds this attribute"] alias symbol myAnnotation; // or alias anything else if a change in necessary.
}

@myAnnotation(arg1, arg2, arg3) class Declaration
{
}

here the "symbol" is passed to the template as the first parameter and the parameters in the parentheses are passes after it. It's basically a thin syntactic sugar over some manual (and very ugly) manual template instantiations (and mixins), so it doesn't add anything new.

Annotations then become a way to statically replace declarations.
This would be perfect to replace

Scoped!MyClass mc;

with:

@scoped MyClass mc;

Which looks quite like a very beautiful built-in syntax, but is actually a library solution.

IMHO, Attributes as they are should stay, but annotations should be added.

P.S. Thank you, Walter very very much for making attributes!!! :-)
November 06, 2012
On 2012-11-06 15:23, Gor Gyolchanyan wrote:

> What if the data in the attribute needs to be specific to the symbol on
> which the attribute is set on? Can you query the symbol from inside the
> attribute?
> What if the attribute needs to change the symbol being defined?
> For instance (using commonly desired syntax):
>
> @flags enum A { ... }
>
> the "flags" attribute would replace the declaraction of A with another
> enum declaration with the same name and same members, but with replaced
> initialization and would static assert(false, "flags enum can't have
> initializers") if any initializers are given.
>
> The existing "[data] declaration" is one thing. It adds compile-time
> data to symbols, which is very very important, but it's not the only
> thing that is needed. What I described above is not quite an attribute,
> but an annotation. The semantics of attributes as Walter made them is
> perfect. The annotation should be  defined like so:
>
> template myAnnotation(alias symbol, annot_args...)
> {
>      // ...
>      ["myAnnoration adds this attribute"] alias symbol myAnnotation; //
> or alias anything else if a change in necessary.
> }
>
> @myAnnotation(arg1, arg2, arg3) class Declaration
> {
> }
>
> here the "symbol" is passed to the template as the first parameter and
> the parameters in the parentheses are passes after it. It's basically a
> thin syntactic sugar over some manual (and very ugly) manual template
> instantiations (and mixins), so it doesn't add anything new.
>
> Annotations then become a way to statically replace declarations.
> This would be perfect to replace
>
> Scoped!MyClass mc;
>
> with:
>
> @scoped MyClass mc;
>
> Which looks quite like a very beautiful built-in syntax, but is actually
> a library solution.
>
> IMHO, Attributes as they are should stay, but annotations should be added.
>
> P.S. Thank you, Walter very very much for making attributes!!! :-)

I like this proposal as well.

-- 
/Jacob Carlborg
November 06, 2012
Am 06.11.2012 14:14, schrieb Adam D. Ruppe:
> On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
>> User Defined Attributes (UDA) are compile time expressions that
>> can be attached to a declaration.
>
> Hmmm, it didn't work on the most important place for my use case,
> function parameters:
>
> void a(["test"] int foo) {
>       pragma(msg, __traits(getAttributes, foo));
> }

sad - but its still very young feature :)

im using something like an description on my methods to describe parameter "features" for an resource manager - something like "read", "write", "copy", "read_write" etc.

to have this at compiletime available by using UDAs on parameters  + an compiletime generator would be absolutely briliant

my vote +1 for UDAs on parameters

November 06, 2012
On 11/6/2012 4:18 AM, Max Samukha wrote:
> Attributes on overloads are critical. Currently fails:

That should work. Will investigate.

November 06, 2012
On 11/6/2012 4:24 AM, angel wrote:
> How do the attributes interact with inheritance ?
> What happens when one inherits an attribute-decorated class ?


The attributes are for the symbol, not the type.
November 06, 2012
On Tuesday, 6 November 2012 at 13:14:50 UTC, Adam D. Ruppe wrote:
> On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
>> User Defined Attributes (UDA) are compile time expressions that can be attached to a declaration.
>
> Hmmm, it didn't work on the most important place for my use case, function parameters:
>
> void a(["test"] int foo) {
>     pragma(msg, __traits(getAttributes, foo));
> }
>

Hmmm, actually it doesn't work in plain function/block scope either.

void a()
{
  ["test"] int foo;
  pragma(msg, __traits(getAttributes, foo));
}
Error: found 'int' when expecting ';' following statement

November 06, 2012
On 11/6/2012 5:57 AM, Jacob Carlborg wrote:
> But I would still like to somehow be able to name an
> attribute. If one just need to mark a symbol, i.e.
>
> @test void foo () {}
>
> Then one either have to use a string literal or something like a dummy
> variable/type.
>
> ["test"] void foo () {}

Which does exactly what you ask for.


> enum test = "test";
>
> [test] void foo () {}

or:

   enum EEE;
   [EEE] void foo() { }

November 06, 2012
On 11/6/2012 5:14 AM, Adam D. Ruppe wrote:
> Hmmm, it didn't work on the most important place for my use case, function
> parameters:

It didn't occur to me to enable that.

November 06, 2012
On 11/6/2012 6:30 AM, dennis luehring wrote:
> Am 06.11.2012 14:14, schrieb Adam D. Ruppe:
>> On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
>>> User Defined Attributes (UDA) are compile time expressions that
>>> can be attached to a declaration.
>>
>> Hmmm, it didn't work on the most important place for my use case,
>> function parameters:
>>
>> void a(["test"] int foo) {
>>       pragma(msg, __traits(getAttributes, foo));
>> }
>
> sad - but its still very young feature :)
>
> im using something like an description on my methods to describe parameter
> "features" for an resource manager - something like "read", "write", "copy",
> "read_write" etc.

But there's already out=write, read=all of them, read_write=ref, copy=not a ref or an out.

I don't know what use UDAs would be for parameters.