April 06, 2012
On 6 April 2012 18:17, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Friday, 6 April 2012 at 15:07:04 UTC, Manu wrote:
>
>> But maybe the function approach has an
>> effect on the simplicity of the expression for a simple attribute, like a
>> single bool?
>>
>
> Meh, it is pretty similar:
>
> struct Serializable { bool yes; }
> bool Serializable(bool yes) { return yes; }
>

Indeed. And with that in mind...


On 6 April 2012 17:56, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:

> @Uuid("...")
> interface MyIntf { }
>
> without explicitly declaring Uuid as attribute. However, I don't see any usage for primitive types:
>
> @5
> @"s"
> @false
>
> I think that allowing values of structs, classes and _eventually_ enums should be enough.
>

I totally agree, although I don't know what enum's offer that can't be equally wrapped in a struct/class? They can probably be skipped as well.


April 06, 2012
On 4/6/12, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:
>> @attribute Author author(string name) { return Author(name);}
>
> Compare it to:
>
> struct Author { string name; }
>
> @Author("John Doe") int x;

I assume we could use templated functions:

struct Author { string name; }
@attribute T temp(T, Args...)(Args args){ return T(args);}
@temp!Author("John Doe") int x;

On 4/6/12, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:
> Compiler can easily deal with structs too:
>
> enum author = Author("John");
> pragma(msg, author.name);

Just throwing this out there that's semi-related: there's a bug w.r.t. struct constructors and enums: http://d.puremagic.com/issues/show_bug.cgi?id=5460
April 06, 2012
> On 4/6/12, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote: struct Author { string name; }

Also, let's not forget the glaring limitation of structs that almost everyone has ran into: you can't define a default ctor.
April 06, 2012
Andrej Mitrovic wrote:
>> On 4/6/12, Piotr Szturmaj<bncrbme@jadamspam.pl>  wrote:
>> struct Author { string name; }
>
> Also, let's not forget the glaring limitation of structs that almost
> everyone has ran into: you can't define a default ctor.

Static opCall() should do the trick:

struct Author
{
    string name;
    static Author opCall()
    {
        Author a;
        a.name = "empty";
        return a;
    }
}

enum a = Author();
pragma(msg, a.name);
April 06, 2012
On 4/6/12, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:
> Static opCall() should do the trick

But it seems like a roundabout way to work around an implementation issue just to enable annotations.

Well anyway as long as we *get* annotations at some point, all will be fine. :)
April 06, 2012
Andrej Mitrovic wrote:
> On 4/6/12, Piotr Szturmaj<bncrbme@jadamspam.pl>  wrote:
>> Static opCall() should do the trick
>
> But it seems like a roundabout way to work around an implementation
> issue just to enable annotations.

What do you mean? You can also initialize structs without default contructor:

struct Author { string name = "empty"; }
// struct Author { string name; } - this works too

enum a = Author();
pragma(msg, a.name);
enum b = Author("test");
pragma(msg, b.name);

I don't think default constructors or opCall are _needed_ for annotations.

> Well anyway as long as we *get* annotations at some point, all will be fine. :)

I'm sure it will!
April 06, 2012
On Friday, 6 April 2012 at 14:23:51 UTC, Steven Schveighoffer wrote:
> On Fri, 06 Apr 2012 10:11:32 -0400, Manu <turkeyman@gmail.com> wrote:
>
>> On 6 April 2012 16:56, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>
>>> On Fri, 06 Apr 2012 09:53:59 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:
>>>
>>> I think this proposal should be merged with Johannes' one.
>>>>
>>>
>>> It is very similar.  I think the main distinction is that I focused on the
>>> fact that the compiler already has a mechanism to check and run CTFE
>>> functions.
>>>
>>
>> Except you're using a function, which I don't follow. How does that work?
>> Where do you actually store the attribute data?
>> Just attaching any arbitrary thing, in particular, a struct (as in Johannes
>> proposal) is far more useful. It also seems much simpler conceptually to
>> me. It's nice when things are intuitive...
>
> You can store a struct, just return it from an attribute function.
>
> e.g.:
>
> @attribute Author author(string name) { return Author(name);}
>
> Why should we be restricted to only structs?  Or any type for that matter?
>
> The benefit to using CTFE functions is that the compiler already knows how to deal with them at compile-time.  i.e. less work to make the compiler implement this.
>
> I also firmly believe that determining what is allowed as attributes should be opt-in.  Just allowing any struct/class/function/etc. would lead to bizarre declarations.
>
> -Steve

I think this proposal pretty much covers what I would expect from 'custom attributes'... but what about adding a D twist, getting "what we annotate" as a template parameter so that one among other things can make use of Template Constraints?


April 06, 2012
On Fri, 06 Apr 2012 10:56:19 -0400, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:

> Steven Schveighoffer wrote:
>> On Fri, 06 Apr 2012 10:11:32 -0400, Manu <turkeyman@gmail.com> wrote:
>>
>>> On 6 April 2012 16:56, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>>>
>>>> On Fri, 06 Apr 2012 09:53:59 -0400, Timon Gehr <timon.gehr@gmx.ch>
>>>> wrote:
>>>>
>>>> I think this proposal should be merged with Johannes' one.
>>>>>
>>>>
>>>> It is very similar. I think the main distinction is that I focused on
>>>> the
>>>> fact that the compiler already has a mechanism to check and run CTFE
>>>> functions.
>>>>
>>>
>>> Except you're using a function, which I don't follow. How does that work?
>>> Where do you actually store the attribute data?
>>> Just attaching any arbitrary thing, in particular, a struct (as in
>>> Johannes
>>> proposal) is far more useful. It also seems much simpler conceptually to
>>> me. It's nice when things are intuitive...
>>
>> You can store a struct, just return it from an attribute function.
>>
>> e.g.:
>>
>> @attribute Author author(string name) { return Author(name);}
>
> Compare it to:
>
> struct Author { string name; }
>
> @Author("John Doe") int x;

so now I must define a type for every attribute?  I'd rather just define a function.

What if I have 20 string attributes, I must define a new attribute type for each one?  This seems like unneeded bloat.

BTW, if I wasn't trying to demonstrate that you could store structs, I would have written:

@attrubte string author(string name) { return name;}

and save the extra bloat associated with declaring another type.  Maybe we could even get this someday:

@attribute author(string name) => name;

I just don't see the need to declare a type that can wrap a string.

You could even add this rule:

if @attribute is placed on a struct, its constructor becomes an @attribute qualified function with the name of the struct as the attribute name.

>> Why should we be restricted to only structs? Or any type for that matter?
>
> When using __traits(getAttributes, ...) you ask for conrete (struct) type and you get it. In case of function you ask for serializable but you get a bool.

It's an example.  you can choose any type you want!  I actually just want the name of the author, I don't care whether that's a struct, or a string.

>
>> The benefit to using CTFE functions is that the compiler already knows
>> how to deal with them at compile-time. i.e. less work to make the
>> compiler implement this.
>
> Compiler can easily deal with structs too:

I concede this is probably a non-issue.

>> I also firmly believe that determining what is allowed as attributes
>> should be opt-in. Just allowing any struct/class/function/etc. would
>> lead to bizarre declarations.
>
> C# has requirement that attributes are classes that derive from base Attribute class. But without that limitation you can do things like:
>
> @Uuid("...")
> interface MyIntf { }
>
> without explicitly declaring Uuid as attribute. However, I don't see any usage for primitive types:
>
> @5
> @"s"
> @false

I don't understand what you are saying here.

> I think that allowing values of structs, classes and _eventually_ enums should be enough.

Any CTFE computed value should suffice.

-Steve
April 06, 2012
On Fri, 06 Apr 2012 12:53:51 -0400, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:

> Andrej Mitrovic wrote:
>> On 4/6/12, Piotr Szturmaj<bncrbme@jadamspam.pl>  wrote:
>>> Static opCall() should do the trick
>>
>> But it seems like a roundabout way to work around an implementation
>> issue just to enable annotations.
>
> What do you mean? You can also initialize structs without default contructor:
>
> struct Author { string name = "empty"; }
> // struct Author { string name; } - this works too

I think the point is, we should disallow:

@Author int x;

-Steve
April 06, 2012
On Fri, 06 Apr 2012 10:46:33 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:

> Constructors are functions too, and the compiler can run them too. I think the implementation should just allow any ctfe-callable symbol to be used as an attribute.

This does make sense.  Not having the ctor be an attribute (or the struct itself) is an easily-worked around limitation (just create a factory function).  It would make sense that you should be able to call a ctor just as well as you can call a function, and not have to create a stub function that simply calls the ctor.

-Steve