November 06, 2012
On Tuesday, 6 November 2012 at 08:20:42 UTC, Walter Bright wrote:
> 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.

Thank you. Now we can stop connecting the dots with hidden
declaration hacks. Yay!

November 06, 2012
On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:

> =====================================================
> User Defined Attributes
> -----------------------
>

Attributes on overloads are critical. Currently fails:

module test;

[1] void foo();
[2] void foo(int x);

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

void main()
{
    foreach (o; __traits(getOverloads, test, "foo"))
    {
        alias Tuple!(__traits(getAttributes, o)) attrs;
        pragma(msg, attrs.stringof);
    }
}

Compiler outputs:
()
()

November 06, 2012
How do the attributes interact with inheritance ?
What happens when one inherits an attribute-decorated class ?
I can picture both situations, when you would like to see the attributes inherited, and when you would prefer them dropped.

November 06, 2012
On 2012-11-06 09:20, Sönke Ludwig wrote:
> 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 '[]'

I agree, I a syntax like this would have been nicer:

@mtype("key" : "value") int a; or @mtype(key : "value") int a;
@mtype("value") int b;
@mtype int c;

-- 
/Jacob Carlborg
November 06, 2012
On 2012-11-06 08:55, 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 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).

This is so cool. Although I would have expected it to have a slightly different syntax. Also have a more key-value like mapping, something like this:

@mtype("key" : "value") int a; or @mtype(key : "value") int a;
@mtype(key : "val1", key2 : "val2") int foo;
@mtype("value") int b;
@mtype int c;

Not it's just a bunch of values attached to a symbol, as I see it.

-- 
/Jacob Carlborg
November 06, 2012
On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
> User Defined Attributes (UDA) are compile time expressions that can be attached to a declaration.

Hmmm, it didn't work on the most important place for my use case, function parameters:

void a(["test"] int foo) {
    pragma(msg, __traits(getAttributes, foo));
}

test.d(1): Error: basic type expected, not [
test.d(1): Error: found 'int' when expecting ')'
test.d(1): Error: semicolon expected following function declaration
test.d(1): Error: no identifier for declarator foo
test.d(1): Error: semicolon expected, not ')'
test.d(1): Error: Declaration expected, not ')'



The reason why this is important to me is I have a nice automatic form builder given a function signature. I'd like to add things like hints about the params that my existing code can take a look at.


(a problem that might remain is being able to reference the parameters outside... I use a ParameterTypeTuple and .stringof right now but that probably won't work for getAttributes. But we can always solve that later.)
November 06, 2012
On Tuesday, 6 November 2012 at 13:08:15 UTC, Jacob Carlborg wrote:
> Also have a more key-value like mapping, something like this:

We can always use custom types to get this kind of thing.

struct key { string value; }

[key("value")] foo
November 06, 2012
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
>

I tried to build DMD git for dpaste, so people can play with UDA but DMD segfaults when building Phobos

Program received signal SIGSEGV, Segmentation fault.
0x0000000000403179 in ClassDeclaration::getAccess(Dsymbol*) ()
(gdb) bt
#0  0x0000000000403179 in ClassDeclaration::getAccess(Dsymbol*) ()
#1  0x0000000000403614 in AggregateDeclaration::accessCheck(Loc, Scope*, Dsymbol*) ()
#2  0x0000000000459f36 in CallExp::semantic(Scope*) ()
#3  0x00000000004ccceb in ExpStatement::semantic(Scope*) ()
#4  0x00000000004d0cdd in CompoundStatement::semantic(Scope*) ()
#5  0x000000000046b830 in FuncDeclaration::semantic3(Scope*) ()
#6  0x0000000000448418 in FuncExp::semantic(Scope*) ()
#7  0x00000000004a0a0a in TypeTypeof::semantic(Loc, Scope*) ()
#8  0x0000000000499b61 in Type::trySemantic(Loc, Scope*) ()
#9  0x000000000044e16e in IsExp::semantic(Scope*) ()
#10 0x0000000000427e4a in StaticIfCondition::include(Scope*, ScopeDsymbol*) ()
#11 0x00000000004058e2 in ConditionalDeclaration::include(Scope*, ScopeDsymbol*) ()
#12 0x0000000000405987 in StaticIfDeclaration::include(Scope*, ScopeDsymbol*) ()
#13 0x0000000000403fe0 in AttribDeclaration::addMember(Scope*, ScopeDsymbol*, int) ()
#14 0x0000000000405add in StaticIfDeclaration::addMember(Scope*, ScopeDsymbol*, int) ()
#15 0x0000000000404015 in AttribDeclaration::addMember(Scope*, ScopeDsymbol*, int) ()


Well, anyways, I fetched package prepared in first post.
So folks, you can play with UDA on http://dpaste.dzfl.pl - by picking DMD2 git - without messing with DMD packages in your OS :)

http://dpaste.dzfl.pl/9c2e8b20

Also if I declare string with UDA inside main() I get error:
http://dpaste.dzfl.pl/909a34c8
November 06, 2012
You can put the attribute on the function.
There are a couple of go libraries that use struct tags in a similar way.
Such as code.google.com/p/gorest
 On 6 Nov 2012 15:15, "Adam D. Ruppe" <destructionator@gmail.com> wrote:

> On Tuesday, 6 November 2012 at 07:55:51 UTC, Walter Bright wrote:
>
>> User Defined Attributes (UDA) are compile time expressions that can be
>> attached to a declaration.
>>
>
> Hmmm, it didn't work on the most important place for my use case, function parameters:
>
> void a(["test"] int foo) {
>     pragma(msg, __traits(getAttributes, foo));
> }
>
> test.d(1): Error: basic type expected, not [
> test.d(1): Error: found 'int' when expecting ')'
> test.d(1): Error: semicolon expected following function declaration
> test.d(1): Error: no identifier for declarator foo
> test.d(1): Error: semicolon expected, not ')'
> test.d(1): Error: Declaration expected, not ')'
>
>
>
> The reason why this is important to me is I have a nice automatic form builder given a function signature. I'd like to add things like hints about the params that my existing code can take a look at.
>
>
> (a problem that might remain is being able to reference the parameters outside... I use a ParameterTypeTuple and .stringof right now but that probably won't work for getAttributes. But we can always solve that later.)
>


November 06, 2012
On 2012-11-06 14:17, Adam D. Ruppe wrote:

> We can always use custom types to get this kind of thing.
>
> struct key { string value; }
>
> [key("value")] foo

Right, good point. But I would still like to somehow be able to name an attribute. If one just need to mark a symbol, i.e.

@test void foo () {}

Then one either have to use a string literal or something like a dummy variable/type.

["test"] void foo () {}

enum test = "test";

[test] void foo () {}

Or

struct test {}

[test()] void foo () {}

-- 
/Jacob Carlborg