View mode: basic / threaded / horizontal-split · Log in · Help
April 06, 2012
Re: Custom attributes (again)
On 4/6/2012 12:49 AM, Alex Rønne Petersen wrote:
> What about type declarations? I think those ought to be supported too. E.g. it
> makes sense to mark an entire type as @attr(serializable) (or the inverse).


That would make it a "type constructor", not a storage class, which we talked 
about earlier in the thread. I refer you to that discussion.
April 06, 2012
Re: Custom attributes (again)
On 06-04-2012 09:54, Walter Bright wrote:
> On 4/6/2012 12:49 AM, Alex Rønne Petersen wrote:
>> What about type declarations? I think those ought to be supported too.
>> E.g. it
>> makes sense to mark an entire type as @attr(serializable) (or the
>> inverse).
>
>
> That would make it a "type constructor", not a storage class, which we
> talked about earlier in the thread. I refer you to that discussion.

To be clear, I don't want annotations on a type declaration to actually 
affect the type. Annotations are just that: Annotations. Nothing else.

Does a design like that still give rise to the semantic issues you 
mentioned (it isn't clear what those are)?

-- 
- Alex
April 06, 2012
Re: Custom attributes (again)
On 4/6/12 3:54 PM, Walter Bright wrote:
> On 4/6/2012 12:49 AM, Alex Rønne Petersen wrote:
>> What about type declarations? I think those ought to be supported too.
>> E.g. it
>> makes sense to mark an entire type as @attr(serializable) (or the
>> inverse).
>
>
> That would make it a "type constructor", not a storage class, which we
> talked about earlier in the thread. I refer you to that discussion.

What's the difference between "type constructor" and "storage class" 
beside the name?
April 06, 2012
Re: Custom attributes (again)
Am Fri, 06 Apr 2012 00:48:34 -0700
schrieb Walter Bright <newshound2@digitalmars.com>:

> On 4/6/2012 12:35 AM, Alex Rønne Petersen wrote:
> > It actually can be a problem. In .NET land, there are many
> > attributes across many projects (and even in the framework itself)
> > with the same names. It turns out that regular namespace lookup
> > rules alleviate this problem.
> 
> 
> Perhaps a better scheme is:
> 
>     enum foo = 3;
> 
>     ...
> 
>     @attr(foo) int x;
> 
> That way, foo will follow all the usual rules.
> 

The last time custom attributes where discussed, a C# like model was
proposed. Is there a good reason why we should deviate from the C#
implementation?

C#:
http://msdn.microsoft.com/en-US/library/48zeb25s(v=vs.80).aspx
http://msdn.microsoft.com/en-US/library/sw480ze8(v=vs.100).aspx
http://msdn.microsoft.com/en-US/library/z919e8tw(v=vs.80).aspx

(C# attributes can be applied to almost everything, therefore sometimes
"disambiguating targets" is necessary. Probably not needed in D):
http://msdn.microsoft.com/en-US/library/b3787ac0(v=vs.80).aspx

Syntax in D would be different of course, but I see absolutely no need
for the redundant (and ugly) @attr.

Declaring a custom attribute:
---------
module std.something;

struct Author
{
   string name;
   public this(string name)
   {
       this.name = name;
   }
}
---------

Using it:
---------
import std.something; //Usual namespace lookup rules apply to attributes

/*
* @Author(param) calls the constructor of the Author struct and
* attaches the struct instance to test. Probably @Author (without
* parenthesis) coud be made to mean std.something.Author.init 
*/
@Author("Johannes Pfau") int test;
---------

Attaching attributes multiple times as in C# should be possible.

Using reflection to get that attribute:
---------
if(__traits(hasAttribute, test, std.something.Author))
{
   Author[] authors = __traits(getAttribute, test,
       std.something.Author);
}
---------

An array is used here to support attaching the same attribute multiple
times. Of course "auto authors = ..." should be usable here too.
April 06, 2012
Re: Custom attributes (again)
On 4/6/12 3:48 PM, Walter Bright wrote:
> On 4/6/2012 12:35 AM, Alex Rønne Petersen wrote:
>> It actually can be a problem. In .NET land, there are many attributes
>> across
>> many projects (and even in the framework itself) with the same names.
>> It turns
>> out that regular namespace lookup rules alleviate this problem.
>
>
> Perhaps a better scheme is:
>
> enum foo = 3;
>
> ...
>
> @attr(foo) int x;
>
> That way, foo will follow all the usual rules.

At least in .Net and Java it's something like this.

1. You declare your attributes. This is something good, because you have 
a place to say "This attribute is used for marking fields as 
non-serializable".

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;
}

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.

---

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;

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.

Now, to implement this is not very much difficult than what you proposed.

1. Introduce the syntax to define attributes. Piece of cake, since it's 
much more or less the syntax of a struct, but functions or nested types 
are not allowed. Parse them into an AttributeDecl or something like that.
2. When the compiler finds @attr(field = value) it uses normal lookup 
rules to find "attr". Then it checks it's an attributes. Then all fields 
are check in turn to see if their type match. You can probably put there 
anything that's compile-time evaluatable, though usually primitive types 
and strings are enough. If a field is not specified, it's type.init will 
be used.
3. The syntax for querying is almost the same as you proposed:

__traits(hasAttribute, x, serializable) // true
__traits(getAttribtue, x, serializable, name) // "Foo"

4. Declare the core attributes in object.di or similar: @safe, @nothrow, 
etc. You can also document them.
5. Probably deprecate __traits(isSafe) and so on, since hasAttribute can 
be used for that.
April 06, 2012
Re: Custom attributes (again)
On 04/06/2012 09:54 AM, Walter Bright wrote:
> On 4/6/2012 12:49 AM, Alex Rønne Petersen wrote:
>> What about type declarations? I think those ought to be supported too.
>> E.g. it
>> makes sense to mark an entire type as @attr(serializable) (or the
>> inverse).
>
>
> That would make it a "type constructor", not a storage class, which we
> talked about earlier in the thread. I refer you to that discussion.

I think what was discussed there is that

@attr(foo) int x;

Wouldn't change the type of x.

@attr(foo) struct Foo{}

Should add additional information to the type Foo. I don't see any 
issues with it, and not supporting it would be very strange.
April 06, 2012
Re: Custom attributes (again)
On 5 April 2012 20:35, Walter Bright <newshound2@digitalmars.com> wrote:

> On 4/5/2012 5:00 AM, Manu wrote:
>
>> C# and Java both have attributes, following these established design
>> patterns, I
>> don't think there should be any mystery over how they should be
>> implemented.
>>
>
> At the Lang.NEXT conference over the last 3 days, I was able to talk to
> many smart people about attributes. But I did find some confusion - are
> they best attached to the variable/function (i.e. "storage class"), or
> attached to the type ("type constructor")? I think the former. Attaching it
> to the type leads to all sorts of semantic issues.
>
> From your list of uses, it looks like attaching it to the variable or
> function is an apropos solution.
>

Yes, most certainly the former. The latter is already possible with tricks
(a trivial template for instance).
An attribute/annotation should associate with select instances/declarations
of things.
I don't think it should affect the type, although this shows a conceptual
problem when referring to existing attributes via the same terminology.
Obviously one might consider 'const', 'pure', etc attributes themselves,
and they clearly do affect the type.
Perhaps that's the key distinction between an '@'
attribute(/'annotation'?), and a no-'@' attribute?
April 06, 2012
Re: Custom attributes (again)
On 5 April 2012 21:32, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/05/2012 08:05 PM, Andrei Alexandrescu wrote:
>
>> On 4/5/12 12:44 PM, deadalnix wrote:
>>
>>> Le 05/04/2012 19:35, Walter Bright a écrit :
>>>
>>>> On 4/5/2012 5:00 AM, Manu wrote:
>>>>
>>>>> C# and Java both have attributes, following these established design
>>>>> patterns, I
>>>>> don't think there should be any mystery over how they should be
>>>>> implemented.
>>>>>
>>>>
>>>> At the Lang.NEXT conference over the last 3 days, I was able to talk to
>>>> many smart people about attributes. But I did find some confusion - are
>>>> they best attached to the variable/function (i.e. "storage class"), or
>>>> attached to the type ("type constructor")? I think the former. Attaching
>>>> it to the type leads to all sorts of semantic issues.
>>>>
>>>> From your list of uses, it looks like attaching it to the variable or
>>>> function is an apropos solution.
>>>>
>>>
>>> They should be attached to declarations.
>>>
>>
>> The question was whether the declaration affects the type of the
>> declared or not.
>>
>> Andrei
>>
>
> Ideally it would be powerful enough to allow changing the type, but most
> applications probably want the type to stay the same.
>

Didn't someone already say there were existing language defined attributes
that could be neatly implemented via libs if the feature were available?
Which ones were they?
April 06, 2012
Re: Custom attributes (again)
On 04/06/2012 11:57 AM, Manu wrote:
> I don't think it should affect the type, although this shows a
> conceptual problem when referring to existing attributes via the same
> terminology. Obviously one might consider 'const', 'pure', etc
> attributes themselves, and they clearly do affect the type.
> Perhaps that's the key distinction between an '@'
> attribute(/'annotation'?), and a no-'@' attribute?

@safe affects the type.
April 06, 2012
Re: Custom attributes (again)
On 4/6/2012 2:41 AM, Johannes Pfau wrote:
> The last time custom attributes where discussed, a C# like model was
> proposed. Is there a good reason why we should deviate from the C#
> implementation?

C# uses a runtime implementation, not a compile time one.
1 2 3 4 5 6 7 8
Top | Discussion index | About this forum | D home