April 06, 2012
On Fri, 06 Apr 2012 09:04:58 -0400, Manu <turkeyman@gmail.com> wrote:

> On 6 April 2012 15:58, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
>> 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.

Correct.

-Steve
April 06, 2012
On Friday, 6 April 2012 at 06:47:56 UTC, Walter Bright wrote:
> I was thinking of something along the lines of what has been proposed here earlier:
>
>   @attr(identifier = expression)

The identifier in there is a liability because of
name conflicts.

Instead, use typeof(expression) to identify it. Since
two types can't have the same fully qualified name,
it will never conflict.


Jacob and I disagreed on some details, but both our
proposals in the last thread had this in common. Java
does it this way, too.

Here's the other thread:
http://forum.dlang.org/thread/bccwycoexxykfgxvedix@forum.dlang.org
April 06, 2012
On Friday, 6 April 2012 at 12:52:27 UTC, Jacob Carlborg wrote:
> Just as we have today with keywords and symbols, I don't see the problem.

Things like safe aren't keywords though. They are just
magic identifiers.

Think of the implementation:

switch(tok.ident) {
   case Id::safe:
   case Id::property:
    // etc for built ins
   default:
    // handle user ones here
}

If you were to define a struct safe {}, which is perfectly
legal D, and try to use it, you won't get what you expect.

It will trigger the case safe before it goes to the default.
So, the user defined one will just be quietly hidden.
April 06, 2012
Manu wrote:
> On 6 April 2012 15:38, Piotr Szturmaj <bncrbme@jadamspam.pl
>     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.

See http://msdn.microsoft.com/en-us/library/b3787ac0%28v=vs.80%29.aspx

Attributes on return values are useful for RPC methods. For example: with attribute, one can specify how return value is serialized/marshalled.

In C#, attributes can be specified on function, parameters and return type _simultaneously_. I don't think we should limit D ones to functions and parameters.
April 06, 2012
Jacob Carlborg wrote:
> 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 {}
>

I think that @target is a solution for simple types, but UDTs may use another one:

struct MyAttr
{
    template Attach(Symbol)
    {
        static if (!is(typeof(Symbol) == class) || !is(typeof(Symbol) : A))
            static assert(0, "MyAttr must be attached to classes derived from class A");
    }
}

This allows more complex target checking possible. Besides above example, some attributes can be mutually exclusive and __traits(hasAttribute, ...) may be used to check that.
April 06, 2012
Le 06/04/2012 14:23, Jacob Carlborg a écrit :
> On 2012-04-06 05:30, Ary Manzana wrote:
>
>> I don't understand the difference between "storage class" and "type
>> constructor". I guess I do. But my answer is the same as deadalnix: they
>> are attached to declarations (at compile time).
>>
>> Can you give us an example of the confusion that arose? I can't
>> understand it without examples.
>>
>> I think it should work like this:
>>
>> @custom
>> class Foo {
>>
>> @ custom
>> void bar() { }
>>
>> void baz() { }
>> }
>>
>> class Other {}
>>
>> __traits(hasAttribute, Foo, 'custom') --> true
>> __traits(hasAttribute, Other, 'custom') --> false
>>
>> // I have no idea how to iterate the members of Foo, or get a reference
>> to the "bar" method... I can't understand what __traits(getMember)
>> returns from the docs...
>
> 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".
>

As foo isn't a declaration, I don't think it is attribute we want here. Or an extension, because it have a lot of consequences.
April 06, 2012
Le 06/04/2012 12:17, Walter Bright a écrit :
> On 4/6/2012 2:18 AM, Ary Manzana wrote:
>> 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?
>
> static const(int)* foo;
>
> static is a storage class. const is a type constructor. There is no type
> 'static'.

Why can't attribute be attached on declaration ?

By the way, this whole qualify the type or something is a big misfeature. annotation should be attached to the declared stuff.

@attr Bar foo() { return Bar(); }

is qualifying « foo ». Qualifying bar make no sense whatsoever.
April 06, 2012
On 4/6/12 1:47 AM, 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.

You also need means to enumerate attributes.

Andrei
April 06, 2012
Le 06/04/2012 12:23, Manu a écrit :
> On 6 April 2012 10:48, Walter Bright <newshound2@digitalmars.com
> <mailto:newshound2@digitalmars.com>> 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.
>
>
> What about:
>
> struct editor
> {
>    this(string name, EditType, Colour = Colour.Default, string
> description = null)
>    {
>      //...
>    }
>
>    blah blah blah
> }
>
> @attr(editor("thing",...blah...))
>
> I don't see the advantage over:
> @editor(...)
>
> ?

+1 I see no additional benefit for this. D have very good lookup rules for looking symbols into modules, so let's use them.
April 06, 2012
On 4/6/12 5:06 AM, Walter Bright wrote:
> 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.

Speaking of the distinction, it would be great if we arranged things such that attributes are a lowering to existing D (i.e. the compiler rewrites a nice attribute syntax into clunky D code you wouldn't want to write by hand).

Lowerings have worked miracles for us in terms of keeping language semantics simple and reducing implementation bugs. We should use them wherever appropriate.


Andrei