View mode: basic / threaded / horizontal-split · Log in · Help
November 06, 2012
User Defined Attributes
References:

http://www.digitalmars.com/d/archives/digitalmars/D/Custom_attributes_again_163042.html

http://www.digitalmars.com/d/archives/digitalmars/D/custom_attribute_proposal_yeah_another_one_163246.html

Inspired by a gallon of coffee, I decided to get it implemented. It's simple, 
based on what D already does (CTFE and heterogeneous tuples), easy to implement, 
easy to understand, and doesn't break anything. It should do everything asked 
for in the above references (except it's not a type constructor).

You can download it here and try it out:

http://ftp.digitalmars.com/dmd2beta.zip

As a bonus, that beta also can generate Win64 executables, and you can even 
symbolically debug them with VS! (Thanks to Rainer Schütze for his invaluable 
help with that).

Here's the rather skimpy and lame spec I banged out:
=====================================================
User Defined Attributes
-----------------------

User Defined Attributes (UDA) are compile time expressions that can be attached
to a declaration. These attributes can then be queried, extracted, and manipulated
at compile time. There is no runtime component to them.

Grammatically, a UDA is a StorageClass:

    StorageClass:
	UserDefinedAttribute

    UserDefinedAttribute:
        [ ArgumentList ]

And looks like:

    [ 3 ] int a;
    [ "string", 7 ]: int b;

If there are multiple UDAs in scope for a declaration, they are concatenated:

    [ 1 ] {
       [ 2 ] int a;        // has UDA's [1,2]
       [ "string" ] int b; // has UDA's [1,"string"]
    }

UDA's can be extracted into an expression tuple using __traits:

    [ 'c' ] string s;
    pragma(msg, __traits(getAttributes, s));

prints:

    tuple('c')

If there are no user defined attributes for the symbol, an empty tuple is returned.
The expression tuple can be turned into a manipulatable tuple:

  template Tuple(T...) {
    alias T Tuple;
  }

  enum EEE = 7;
  ["hello"] struct SSS { }
  [3] { [4][EEE][SSS] int foo; }

  alias Tuple!(__traits(getAttributes, foo)) TP;

  pragma(msg, TP);
  pragma(msg, TP[2]);

prints:

  tuple(3,4,7,(SSS))
  7

and of course the tuple types can be used to declare things:

  TP[3] a;    // a is declared as an SSS

The attribute of the type name is not the same as the attribute of the variable:

  pragma(msg, __traits(getAttributes, typeof(a));

prints:

    tuple("hello")

Of course, the real value of UDA's is to be able to create user defined types with
specific values. Having attribute values of basic types does not scale.
The attribute tuples can be manipulated like any other tuple, and
can be passed as the argument list to a template.

Whether the attributes are values or types is up to the user, and whether later
attributes accumulate or override earlier ones is also up to how the user 
interprets them.
November 06, 2012
Re: User Defined Attributes
On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
> References:
>
> http://www.digitalmars.com/d/archives/digitalmars/D/Custom_attributes_again_163042.html
>
> http://www.digitalmars.com/d/archives/digitalmars/D/custom_attribute_proposal_yeah_another_one_163246.html
>
> Inspired by a gallon of coffee, I decided to get it 
> implemented. It's simple, based on what D already does (CTFE

["*drool*", "totally perfect awesomeness"] Thanks!
November 06, 2012
Re: User Defined Attributes
Wow, that's a surprise! Just yesterday I was thinking that it would be
really nice to have them for a piece of code ;)

But shouldn't we keep the syntax closer to normal attributes and other
languages(*)? I see a lot of arguments for doing that, with the only
counter-argument that they would be in the same namespace as the
built-in attributes (which should not be that bad, as this is very low
level language stuff).

(*) i.e. @mytype or @("string") and without the '[]'
November 06, 2012
Re: User Defined Attributes
On 11/6/2012 12:15 AM, Tove wrote:
> ["*drool*", "totally perfect awesomeness"] Thanks!


The neato thing is I realized I could just connect the dots on what D already 
does well - CTFE, tuples, and templates. The actual features can now be added by 
library routines.
November 06, 2012
Re: User Defined Attributes
On 11/6/2012 12:20 AM, Sönke Ludwig wrote:> But shouldn't we keep the syntax 
closer to normal attributes and other
> languages(*)? I see a lot of arguments for doing that, with the only
> counter-argument that they would be in the same namespace as the
> built-in attributes (which should not be that bad, as this is very low
> level language stuff).
>
> (*) i.e. @mytype or @("string") and without the '[]'


We can debate the syntax. I don't have a store set by this one. I was more 
interested in getting the semantics right. Anyhow, it's nice to have a working 
prototype to experiment with rather than a paper airplane.
November 06, 2012
Re: User Defined Attributes
On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
> -snip-

It doesn't look like it would be possible to schedule any runtime 
code using this, meaning they're not usable for stuff like 
registering types for serialization support, or doing runtime 
linking when attached to a function pointer, etc.

Even with user defined types or functions used in the attribute, 
the type or function itself doesn't know anything about the 
symbol it is being attached to, so it's quite limited what it can 
do.

Compared to other prevalent UDA systems, like C#'s, I'd say that 
this one is extremely limiting due to the two above points.

I'd love to hear some examples of what this particular take on 
UDAs allows in D, though.
November 06, 2012
Re: User Defined Attributes
On 11/6/2012 12:39 AM, Jakob Ovrum wrote:> On Tuesday, 6 November 2012 at 
07:55:51 UTC, Walter Bright wrote:
>> -snip-
>
> It doesn't look like it would be possible to schedule any runtime code using
> this, meaning they're not usable for stuff like registering types for
> serialization support, or doing runtime linking when attached to a function
> pointer, etc.

Since D allows one to inquire and get a list of symbols, one can then iterate 
over them at compile time to determine which are serializable (or have some 
other specific attribute).
November 06, 2012
Re: User Defined Attributes
On Tuesday, 6 November 2012 at 08:42:44 UTC, Walter Bright wrote:
> Since D allows one to inquire and get a list of symbols, one 
> can then iterate over them at compile time to determine which 
> are serializable (or have some other specific attribute).

Yes, but somewhere you have to put startup code pointing in the 
general direction of where the attributes are used (like a 
module), it's not automatic. A static constructor cannot be used 
because it has no idea where to look.

But, I yield until someone comes up with actual examples of how 
these UDAs are useful, because I can't think of anything 
interesting at the moment. I guess I should go read over the old 
discussions you linked (I remember participating, but can't 
remember any specifics).
November 06, 2012
Re: User Defined Attributes
On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
> snip

Nice to hear because it was unexpected and was requested 
prevously by community.
November 06, 2012
Re: User Defined Attributes
On 11/6/2012 12:42 AM, Walter Bright wrote:
> Since D allows one to inquire and get a list of symbols, one can then iterate
> over them at compile time to determine which are serializable (or have some
> other specific attribute).


To emphasize, the User Defined Attributes thing is completely a compile time 
feature. However, a user defined runtime system can be built on top of it.

It gives the best of both worlds.
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home