April 06, 2012
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
April 06, 2012
On 6 April 2012 17:17, Adam D. Ruppe <destructionator@gmail.com> wrote:

> On Friday, 6 April 2012 at 14:11:42 UTC, Manu wrote:
>
>> Except you're using a function, which I don't follow.
>>
>
> It is pretty simple: the return value of the function
> is stored in the compiler, the same as all the other
> proposals.
>
> The struct thing is the same, really. You're just calling
> a constructor there instead of a regular function.
>
>
> Really, of the... what five proposals out there now? But
> they are all almost the same. A constructor, a function
> call, an expression, or a field initializor list all
> give the same result - they all return a piece of data,
> which is attached to the declaration in the compiler.
>
> We're just quibbling over details. I say we just forget about that and pick one to make this happen.
>
> I barely even care which one right now.
>

Ah okay, I see now. You're just using a creator, instead of a constructor.
Yeah fine, whatever.
I'm not quibbling over details, it just wasn't clear to me at all from your
syntax what it was you were actually doing (see: intuitive).

The only thing I care about is that I can associate an arbitrary data
struct, and ideally, the syntax is intuitive and minimal.
I prefer to use the constructor personally (I think it produces a much
simpler/intuitive syntax), and I also like that the '@attribute' keyword is
not necessary in Johannes version, but I really don't care. Whatever works
best in practise, as long as the basic premise is met.


April 06, 2012
On 6 April 2012 17:23, Steven Schveighoffer <schveiguy@yahoo.com> wrote:

> 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.
>

Yep, I see now. If this is significantly simpler, then so be it. Whatever gets it done. This certainly meets my requirements.


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.
>

I see your point, and I also had this thought. I'm on the fence though, not
sure if it's valuable or not.
Does this approach really change that though? It could return anything it
likes, and then it's no different than binding one of those directly.


April 06, 2012
On 04/06/2012 03:56 PM, Steven Schveighoffer 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.
>
> -Steve

Checking and running are basically the same thing. The compiler can run functions that are only partially ctfe-able.

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.
April 06, 2012
Looks good to me.

The missing piece is:

>You also need means to enumerate attributes.

>Andrei


-- 
Dmitry Olshansky
April 06, 2012
On 6 April 2012 17:47, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:

> Looks good to me.
>
> The missing piece is:
>
> >You also need means to enumerate attributes.
>

There are well established patterns for enumerating traits (ie. allMembers
and friends)


April 06, 2012
On 04/06/2012 04:23 PM, Steven Schveighoffer wrote:
> Why should we be restricted to only structs? Or any type for that matter?
>

A restriction to only structs is not a restriction because structs can have arbitrary field types.

> 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.
>

It is exactly the same amount of work because CTFE is able to execute struct constructors.

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

> 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.

> 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:

enum author = Author("John");
pragma(msg, author.name);

> 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 think that allowing values of structs, classes and _eventually_ enums should be enough.
April 06, 2012
On 6 April 2012 17:53, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/06/2012 04:23 PM, Steven Schveighoffer wrote:
>
>> Why should we be restricted to only structs? Or any type for that matter?
>>
>>
> A restriction to only structs is not a restriction because structs can have arbitrary field types.
>
>
>  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.
>>
>>
> It is exactly the same amount of work because CTFE is able to execute struct constructors.
>

The only real difference I see, is at the end of the day, the one level of
indirection (the function call) allows you to create an attribute with a
different name than struct that defines it. Otherwise they would seem to be
functionally equivalent.
Chances are, the creator function would just execute the struct's
constructor internally anyway. But maybe the function approach has an
effect on the simplicity of the expression for a simple attribute, like a
single bool?
I suppose a single bool attribute wouldn't work so well declared the
constructor way, it really does need the name it would inherit from the
creator function...


April 06, 2012
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; }