April 06, 2012
On 2012-04-06 12:28, Walter Bright wrote:

> Name collisions with other @ attributes.
>

Just as we have today with keywords and symbols, I don't see the problem.

-- 
/Jacob Carlborg
April 06, 2012
On 6 April 2012 15:38, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:

> Jacob Carlborg wrote:
>
>> I would like to have the possibility to attach attributes to types and parameters as well. Some think like this:
>>
>> class Bar
>> {
>> @not_null(Foo) bar (@custom int a) {}
>> }
>>
>> Where @not_null is attached to "Foo" and @custom is attached to "a".
>>
>
> Do you mean return type? I think your syntax has some serious disadvantages. Consider parameters and multiple attributes.
>
> For return types I'd like to see something like this:
>
> @return: not_null
> @return: MyAttr("foo")
> Foo bar(@custom int a) {}
>
> This is similar to C#'s [return: MyAttr]. Alternatively it might be:
>
> @return(not_null)
> @return(MyAttr("foo"))
>

There's no need to attribute a return value. A) I think you're confusing it
with attributing *types* again, and B) you can just attribute the function
its self, and have access to precisely the same information.
You can't attribute a return value, since attributes aren't transferred
along with assignments, they are bound to their respective declaration.


April 06, 2012
On Fri, 06 Apr 2012 03:54:15 -0400, Walter Bright <newshound2@digitalmars.com> 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 there is a huge misunderstanding here.

A type constructor alters a type.  Annotations are not type constructors.

for example:

class C {}

@foo class D {}

@foo C c;
@foo2 D d;
D d2 = d;

In all these cases, the @foo or @foo2 affects the *declaration*, not the *type*.  So:

1. D's type is not affected, it's still class D.  But an annotation has been stored on the *symbol* D, such that it can be looked up later.
2. annotations on variables do *not* affect the type of the variable.  The assignment to d2 works fine.
3. The following symbols have annotations attached to them:
  C: none
  D: @foo
  c: @foo
  d: @foo2
  d2: none

Note that d and d2 have no annotations attached even though they are of type D.  Because the type isn't affected by annotations.

An annotation is simply metadata, stored in the compiler, and looked up via compiler directives.  Optionally (and I would encourage this), TypeInfo would store annotations on type declarations for retrieval at runtime.

-Steve
April 06, 2012
On 2012-04-06 14:31, Timon Gehr wrote:

> @not_null cannot be attached to "Foo". It would have to create a new
> symbol @not_null(Foo). And then, all the concerns Walter has raised apply.

Hmm, I guess. But it would be nice to have :)

-- 
/Jacob Carlborg
April 06, 2012
On 6 April 2012 15:58, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> On Fri, 06 Apr 2012 03:54:15 -0400, Walter Bright < newshound2@digitalmars.com> 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 there is a huge misunderstanding here.
>
> A type constructor alters a type.  Annotations are not type constructors.
>
> for example:
>
> class C {}
>
> @foo class D {}
>
> @foo C c;
> @foo2 D d;
> D d2 = d;
>
> In all these cases, the @foo or @foo2 affects the *declaration*, not the *type*.  So:
>
> 1. D's type is not affected, it's still class D.  But an annotation has
> been stored on the *symbol* D, such that it can be looked up later.
> 2. annotations on variables do *not* affect the type of the variable.  The
> assignment to d2 works fine.
> 3. The following symbols have annotations attached to them:
>  C: none
>  D: @foo
>  c: @foo
>  d: @foo2
>  d2: none
>
> Note that d and d2 have no annotations attached even though they are of type D.  Because the type isn't affected by annotations.
>

Just to clarify, typeof(d) and typeof(d2) (ie, both D's) are still
annotated with foo, right? This is precisely how I imagine it to be.

An annotation is simply metadata, stored in the compiler, and looked up via
> compiler directives.  Optionally (and I would encourage this), TypeInfo would store annotations on type declarations for retrieval at runtime.
>

I agree, and I would also encourage this.


April 06, 2012
On 6 April 2012 15:13, deadalnix <deadalnix@gmail.com> wrote:

> Le 06/04/2012 11:41, Johannes Pfau a écrit :
>
>  Am Fri, 06 Apr 2012 00:48:34 -0700
>> schrieb Walter Bright<newshound2@digitalmars.**com<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/48zeb25s(v=vs.80).aspx>
>> http://msdn.microsoft.com/en-**US/library/sw480ze8(v=vs.100).**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<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<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.
>>
>>
> That is a really nice proposal !
>

This is precisely how I have always imagined the system working. Walter: can you comment why you think this is not do-able, or not a good way to go about it?


April 06, 2012
On 2012-04-06 14:38, Piotr Szturmaj wrote:

> Do you mean return type? I think your syntax has some serious
> disadvantages. Consider parameters and multiple attributes.
>
> For return types I'd like to see something like this:
>
> @return: not_null
> @return: MyAttr("foo")
> Foo bar(@custom int a) {}
>
> This is similar to C#'s [return: MyAttr]. Alternatively it might be:
>
> @return(not_null)
> @return(MyAttr("foo"))

Hmm, or something like how Java does it. You attached this information when you declare the attribute:

@Retention(RetentionPolicy.RUNTIME) // Make this annotation accessible at runtime via reflection.
 @Target({ElementType.METHOD})  // This annotation can only be applied to class methods.

public @interface Tweezable {
}

Or with another syntax:

@attribute @target(type) struct not_null {}

-- 
/Jacob Carlborg
April 06, 2012
On 2012-04-06 14:55, Manu wrote:
> On 6 April 2012 15:38, Piotr Szturmaj <bncrbme@jadamspam.pl
> <mailto:bncrbme@jadamspam.pl>> wrote:
>
>     Jacob Carlborg wrote:
>
>         I would like to have the possibility to attach attributes to
>         types and
>         parameters as well. Some think like this:
>
>         class Bar
>         {
>         @not_null(Foo) bar (@custom int a) {}
>         }
>
>         Where @not_null is attached to "Foo" and @custom is attached to "a".
>
>
>     Do you mean return type? I think your syntax has some serious
>     disadvantages. Consider parameters and multiple attributes.
>
>     For return types I'd like to see something like this:
>
>     @return: not_null
>     @return: MyAttr("foo")
>     Foo bar(@custom int a) {}
>
>     This is similar to C#'s [return: MyAttr]. Alternatively it might be:
>
>     @return(not_null)
>     @return(MyAttr("foo"))
>
>
> There's no need to attribute a return value. A) I think you're confusing
> it with attributing *types* again, and B) you can just attribute the
> function its self, and have access to precisely the same information.
> You can't attribute a return value, since attributes aren't transferred
> along with assignments, they are bound to their respective declaration.

It depends on what we want out of attributes.

-- 
/Jacob Carlborg
April 06, 2012
On 2012-04-06 14:58, Steven Schveighoffer wrote:

> An annotation is simply metadata, stored in the compiler, and looked up
> via compiler directives. Optionally (and I would encourage this),
> TypeInfo would store annotations on type declarations for retrieval at
> runtime.
>
> -Steve

Yes, annotations/attributes should be accessible at both compile time and runtime.

-- 
/Jacob Carlborg
April 06, 2012
On 2012-04-06 08:47, Walter Bright 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.
>
> I was thinking of something along the lines of what has been proposed
> here earlier:
>
> @attr(identifier = expression)
>
> as a storage class, like:
>
> @attr(foo = bar + 1) int x;
>
> and then:
>
> __traits(hasAttribute, x, foo)
>
> would return true, and:
>
> __traits(getAttribute, x, foo)
>
> would return the expression (bar+1). The expression would be
> compile-time only, evaluated at the point of declaration.
>
> The implementation is simple enough, just attach to each symbol an array
> of (identifier,expression) pairs.
>
> You could also omit the expression, and just have:
>
> @attr(bar) int y;

Again, this is my proposal:

http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_user_defined_attributes_161624.html#N161742

-- 
/Jacob Carlborg