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

Steven Schveighoffer wrote:
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.

So declaration is always needed, no matter what attribute is.

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

I don't see advantage of functions here, twenty of them is also a bloat. Different types give you different _names_ for different purposes. Those _names_ are crucial to support the attributes.

How do you get list of all attributes with your function based proposal? You can get a string attribute but you don't know which function generated it. You don't know if it was serializable, author or whatever.

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:

As above, declaring another function is also a bloat.

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

Consider struct constructors as equivalent of functions proposed by you. Here you declare a type, there you declare a function. They're very similar, besides that struct type _describes_ the attribute. A function on the other side just returns a value, which doesn't have any name attached to it.

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.

Yes, but my point is that you get a bool and you don't know which of the functions returned it, as many of them can return 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:

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.

"Just allowing any struct/class/function/etc. would
lead to bizarre declarations."

Allowing _any_ type would indeed lead to bizarre declarations, but I think that allowing any struct or class may be useful.

Alternatively structs or classes may require some additional member. This will allow only selected types to work as attributes.

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

Any CTFE computed value should suffice.

I think that list of attributes should be a list of user defined types. You can always write a function to construct them, but anyway you get named user defined type (like struct). Named type easily disambiguates between different attributes without resorting to name-value solutions.

This is how it's done in C# by the way.

Reply via email to