April 06, 2012
Piotr Szturmaj wrote:
> @myModule.pure
> @pure
> void fn() {}

should be:

@myModule.safe
@safe
void fn() {}
April 06, 2012
On 04/06/2012 12:16 PM, Walter Bright wrote:
> On 4/6/2012 1:15 AM, Alex Rønne Petersen wrote:
>> 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.
>
> What would an annotation on a type mean if it does not affect the type?

I don't get that either, it has to affect the type. It does not have any effects on the semantics of instances on the type though. Name mangling can stay the same though.

> Would it just be baggage carried along?

Yes.

> If so, how would that affect types inside of a template, where the type was passed as a type
> constructor?

How do you pass a type as a type constructor?

> How would type inference work?

Just as it does now.

> Would an alias carry or drop the baggage?

Carry. An alias does not change the referenced symbol.

> How would overloading work?
> How would covariance work?

As they do now. Custom attributes don't have semantic meaning recognised by the compiler. They are just data.

> It's a maze of complex decisions.
>

I think you can add a list of annotations to the class in the AST that represents a declaration (the common superclass of all declarations) and everything will just work.

>
>> Does a design like that still give rise to the semantic issues you
>> mentioned (it
>> isn't clear what those are)?
>
> Yes.
>
> (I know Java does this. But Java has a trivial type system compared with
> D. It doesn't even have type aliases. It doesn't have type constructors.
> Etc.)

I think there is some sort of communication problem, because the feature that is being requested is quite simple. It would probably be valuable if you could point out the issues you see in detail (using example code.)


April 06, 2012
On 04/06/2012 12:17 PM, Walter Bright wrote:
> 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'.

Still, the 'static' in

static struct S{
   // ...
}

Affects S. Correct?
April 06, 2012
On 6 April 2012 13:28, Walter Bright <newshound2@digitalmars.com> wrote:

> On 4/6/2012 3:23 AM, Manu wrote:
>
>> What about:
>>
>> struct editor
>> {
>>   this(string name, EditType, Colour = Colour.Default, string description
>> = null)
>>   {
>>     //...
>>   }
>>
>>   blah blah blah
>> }
>>
>> @attr(editor("thing",...blah..**.))
>>
>
> Are you really changing the arguments for every declaration? Or is it one set that is repeated everywhere?
>

Of course, what's the point otherwise? This is the very definition of
annotation.
Everything needs to be exposed in the editor differently.

The power of attributes are that they are tightly syntactically bound to the items they attribute. Nobody can change any class/struct without having the syntax force them to make any necessary corrections to their attributes too.


I don't see the advantage over:
>> @editor(...)
>>
>> ?
>>
>
> Name collisions with other @ attributes.
>

If they were declared as normal structs, they would follow normal namespace rules.

@company.lib.MyAttribute(...) should also be a valid expression.

The only collisions are @trusted, @safe... I think programmers can handle a
few reserved keywords.
I already can't go and name a variable whatever I want for the same
reason: int private = 10;


April 06, 2012
On 04/06/2012 12:53 PM, Walter Bright wrote:
> On 4/6/2012 3:27 AM, Ary Manzana wrote:
>>> @safe, @nothrow, etc., require a lot of semantic support in the
>>> compiler. They cannot pretend to be user defined attributes.
>>
>> Yes they can. That's how it is done in C# and Java. In fact, IUnknown is
>> pretending to be an interface and has semantic support in the compiler.
>
> All the semantics of @safe are in the compiler. None of it can be user
> defined. There's just no point to trying to make it user defined. It's
> like trying to make int user defined.
>
> IUnknown's semantics are nearly all user-defined.
>

The proposal is not to make the semantics of @safe user defined. I think he proposes to make 'safe' a symbol that is looked up like an user defined symbol.

Some languages do the same for the built-in integer type.
April 06, 2012
On 04/06/12 11:18, 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?

@attr(deprecated) struct T { int blah; } // every instance of S now marked with it.

struct S { int blah; }
@attr(deprecated) S si;  // just si marked; think "static S si;" etc


I actually don't like the proposed scheme - it's both way to verbose and not nearly sufficient.

I have to leave soon and don't have the time to fully describe the problems, but just a few key points:

- Both of the above should work; the "storage class" is the more important part.
  Wouldn't just having the type-attributes automatically propagate (as a default
  "storage class") to the instances, w/o affecting the type in any way, be enough?
- If the above would work, then there has to be a way to remove an attribute from
  some instances.
- Attributes needs to be declared in some way, otherwise a typo will go undetected
  and you may not notice it until it's too late. Think "@attr(serialisable)" etc
- Attributes need to be mergeable, ie you really don't want to mark a significant
  number of symbols as serializable, exported-to-X, exported-to-Y etc. Something
  like
  "alias @attr("serializable", "export_X", "export_Y") new_attr"; @attr(new_attr) int i;"
  might work.
- At the very least "__traits(getAttribute, x, foo)" needs to be something like
  "__traits(@attr, x, foo); even better would be "x.@attr("foo");".
- Should attributes be strings? That would avoid clashes with keywords. OTOH
  that would mean that attribute definitions needs to use different syntax than
  plain structs. Hmm, maybe that would be a good thing anyway.
- Namespaces. There needs to be a system NS and a compiler-specific NS. So that
  you can do things like @attr(__GNU, "flatten", "hot") instead of
  "pragma(GNU_attribute, flatten, hot)".
- Null/empty attributes, ie "alias @attr() new_attr;", should work; necessary eg
  when the compiler lacks support for certain features.

There are probably many more issues, these are just the few obvious ones that immediately come to mind.

artur
April 06, 2012
On 6 April 2012 13:23, Walter Bright <newshound2@digitalmars.com> wrote:

> On 4/6/2012 2:54 AM, Timon Gehr wrote:
>
>> Should add additional information to the type Foo. I don't see any issues
>> with
>> it, and not supporting it would be very strange.
>>
>
> How would:
>
>   @attr(foo) int x;
>   int y;
>
> work? Are x and y the same type or not?


Yes they are the same type.



> Now, consider:
>
>   auto c = b ? x : y;
>

c was not attributed, and has no attributes.
@blah auto c = b ? x : y; // NOW 'c' is attributed with 'blah', as useless
as that is :)

Attributes are on the declaration, and not passed around.


April 06, 2012
On 4/6/12 7:09 PM, Timon Gehr wrote:
> On 04/06/2012 12:53 PM, Walter Bright wrote:
>> On 4/6/2012 3:27 AM, Ary Manzana wrote:
>>>> @safe, @nothrow, etc., require a lot of semantic support in the
>>>> compiler. They cannot pretend to be user defined attributes.
>>>
>>> Yes they can. That's how it is done in C# and Java. In fact, IUnknown is
>>> pretending to be an interface and has semantic support in the compiler.
>>
>> All the semantics of @safe are in the compiler. None of it can be user
>> defined. There's just no point to trying to make it user defined. It's
>> like trying to make int user defined.
>>
>> IUnknown's semantics are nearly all user-defined.
>>
>
> The proposal is not to make the semantics of @safe user defined. I think
> he proposes to make 'safe' a symbol that is looked up like an user
> defined symbol.
>
> Some languages do the same for the built-in integer type.

The compiler does the same for TypeInfo, TypeInfo_ClassDeclaration or what ever, Object, etc.

I'm just proposing @safe to be seen as a user-defined attribute, but implemented in the compiler with special semantic.

I'm saying it so that lookup rules become easier: just search. No special cases like "if the attribute name is safe". Of course, treat the special cases later inside the compiler code.
April 06, 2012
On 6 April 2012 14:03, Timon Gehr <timon.gehr@gmx.ch> wrote:
>
> It's a maze of complex decisions.
>>
>
> I think you can add a list of annotations to the class in the AST that represents a declaration (the common superclass of all declarations) and everything will just work.


Yeah, I always imagined it being about that simple too... are you able to proof the concept?


(I know Java does this. But Java has a trivial type system compared with
>> D. It doesn't even have type aliases. It doesn't have type constructors. Etc.)
>>
>
> I think there is some sort of communication problem, because the feature that is being requested is quite simple. It would probably be valuable if you could point out the issues you see in detail (using example code.)


Indeed.


April 06, 2012
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>:
>
>> 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.
>

That is a really nice proposal !