Custom attributes (again)

Timon Gehr timon.gehr at gmx.ch
Fri Apr 6 03:29:59 PDT 2012


On 04/06/2012 12:12 PM, Walter Bright wrote:
> On 4/6/2012 2:50 AM, Ary Manzana wrote:
>> The syntax in Java for declaring an attribute:
>>
>> public @interface Foo {
>> String xxx;
>> int yyy;
>> }
>>
>> In D maybe @interface could be used to (in order to avoid introducing
>> another
>> keyword... or maybe use @attribute instead):
>>
>> @attribute Foo {
>> string xxx;
>> int yyy;
>> }
>
> I don't see the need for creating a new kind of symbol.
>

It would behave like a struct anyway. The issue is whether any struct 
should be allowed to be used as an attribute, or whether a runtime 
instance of an attribute can be created.

Syntax could just as well be this:

@attribute struct Foo {
     // ...
}

>
>> 2. You use them by using their names. What you are proposing if for
>> attribute
>> foo to be @attr(foo). But in Java it's @foo.
>>
>> So in Java you would use that attribute like this:
>>
>> @Foo(xxx = "hello", yyy = 1);
>> void func() {}
>>
>> Then you can get the "Foo" attribute in func, and ask for it's xxx and
>> yyy.
>
> This is a runtime system.
>

In Java, yes. But the general scheme works well even at compile time.

It is possible to evaluate struct constructors at compile time.

enum Foo attr = __traits(getAttribute, func, Foo);

>
>> Now, your proposal is much simpler and it will become inconvenient in
>> some
>> cases. For example suppose you want to provide attributes for
>> serialization (I
>> guess the classic example). With your proposal it would be:
>>
>> /// This is actually an attribute. Use this together with
>> serialized_name.
>> enum serialize = 1;
>> enum serialized_name = 2;
>>
>> @attr(serialize = true, serialized_name = "Foo")
>> int x;
>
> No, it would be:
>
>     enum serialize = true;
>     enum serialize_name = "Foo";
>     @attr(serialize, serialized_name) int x;
>

I don't see how that would work. Do you propose to define attributes 
based on the mapping of the name of random manifest constants to their 
value? That would be a kludgy hack.

> There would be no initialization in the @attr syntax.
>
>> Now, with the way things are done in Java and C#:
>>
>> /// Marks a field to be serialized.
>> @attribute serialize {
>> /// The name to be used.
>> /// If not specified, the name of the member will be used instead.
>> string name;
>> }
>>
>> @serialize(name = "Foo")
>> int x;
>>
>> You can see the syntax is much cleaner. The attribute declaration also
>> serves as
>> documentation and to group attributes related to the serialization
>> process.
>
> I don't see that it is cleaner

I think it is cleaner on a conceptual level, even if the syntax was

@attr(serialize("Foo"))

> - there's no particular reason why a new
> symbol type needs to be introduced.
>

There is not strictly a need for a _new_ symbol type, but attribute 
lookup should definitely be symbol based and not string/value based. Why 
would there be any benefit in bypassing the module system for user 
defined attributes?



More information about the Digitalmars-d mailing list