Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe

On the ride over here today, I had a thought that
I think neatly solves the user defined attribute
question.

enum Serializable { yes, no }

@note(Serializable.yes) int a;


We introduce two new things to the language:

1) the @note(expression) attribute. You can put
as many "notes" on a declaration as you want by
simply listing them.

The expression inside is appended to a list on
the declaration.

This would be valid on variables, functions,
function parameters, struct members, etc.

2) __traits(getNotes, decl). This returns a tuple
of all the note expressions.

foreach(i, exp; __traits(getNotes, a)) {
   static assert(is(typeof(exp) == Serializable);
   static assert(exp == Serializable.yes);
}




This simple extension to the language enables libraries,
using existing traits to navigate symbols, to get
additional information about things and implement it
however.

The lack of user defined attributes is D's biggest missed
opportunity right now, and I think this simple proposal
will plug that hole.



Previous user-defined attribute proposals have had counter
arguments like these:

1) how do you define what is and is not a valid attribute?

Here, the answer is pretty simple: you can put whatever notes
you want on the thing. Whether the library uses it or not
is up to it.

It has to be a valid type - so the compiler will catch
typos and whatnot - but it doesn't have to be used unless
you ask for it.


2) OK, how do you namespace things so different libraries don't
get different results?

That's where the beauty of the expression type comes in: D
already has namespaces. foo.Serializable != bar.Serializable,
so there's no conflict.

We simply declare types. The enum X {yes, no} pattern is already
common in Phobos, and is also the best way to express a bool 
condition
here. (Technically, @note(true) would compile, but it'd be much 
less

useful than declaring a name for the note too, with an enum.)

Name conflicts is a problem already solved by the language.


3) Can we have shared attributes, with declared names so people
know what to use in their own libraries?

Yes, we could add some to std.traits or make a new std.notes that
declare some common items as enums.

Though, I think having the types declared in the modules that use
them is generally more useful.


But, again, the library problem is already solved, and we're
just using that!





I think this is a winner... and I think I can do it in the
compiler in less time than it will take to convince git to
give me a clean pull request.


Am I missing anything?


Re: Proposal: user defined attributes

2012-03-16 Thread Manu
On 16 March 2012 15:35, Adam D. Ruppe  wrote:

> @note(Serializable.yes) int a;
>

Surely the term you're looking for here is @annotate(...) ?

This simple extension to the language enables libraries,
> using existing traits to navigate symbols, to get
> additional information about things and implement it
> however.
>
> The lack of user defined attributes is D's biggest missed
> opportunity right now, and I think this simple proposal
> will plug that hole.
>

I agree it's a very big hole against popular competing languages (Java, C#).

Previous user-defined attribute proposals have had counter
> arguments like these:
>
> 1) how do you define what is and is not a valid attribute?
>
> Here, the answer is pretty simple: you can put whatever notes
> you want on the thing. Whether the library uses it or not
> is up to it.
>

What if you want to annotate with a variable? Each instance may need to
hold some attribute state. This is extremely common, particularly in
serialisation systems which typically perform lazy updates, and need some
additional state for that.


> 2) OK, how do you namespace things so different libraries don't
> get different results?
>

Surely this is just as easy: @modulename.attribute int myThing;


> Am I missing anything?
>

 I think it only solves half the problem. There are certainly cases where
you just want to annotate with some sort of tag, so you can know to do
something special in this thing's case, but there are also times where you
want to associate some variable data with each instance.

Perhaps that's the key distinction between 'annotation' and a 'custom
attributes' .. an annotation this way is a shared compile time constant,
associating with its type info, as you suggest. A custom attribute is an
instance-specific association vontaining variable data.
I'd suggest that @annotate(someEnum) could work effectively just as you
suggest, but it doesn't fill the requirement for custom attributes, which
could be implemented separately, something like:

attribute myAttribute
{
  this(int something);

  bool bNeedsAttention;

  property void refresh(bool bRefresh) { bNeedsAttention = bRefresh; }
}

@myAttribute(10) int thing;

thing.refresh = true;


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe

On Friday, 16 March 2012 at 14:11:35 UTC, Manu wrote:

Surely the term you're looking for here is @annotate(...) ?


Meh, I don't care that much about names. I went
with "note" anticipating people would complain about
@add_user_defined_attribute() being too long :)



What if you want to annotate with a variable?


That *might* work because a variable is an expression too.
I'm not sure though. Will probably have to implement to
know for sure.

Of course, a constant can be represented as a struct
for name and value:

struct Description { string s; }

@note(Description("yada yada yada")) int a;



Surely this is just as easy: @modulename.attribute int myThing;


Yeah, I think so. I remember this being a counterpoint
last time we talked about it, but I don't recall the
specific argument made.

Perhaps that's the key distinction between 'annotation' and a 
'custom attributes' .. an annotation this way is a shared 
compile time constant, associating with its type info, as you 
suggest. A custom attribute is an instance-specific association 
vontaining variable data.


Yeah, "annotation" might be the better word. That's
what I want here, but too late to change the subject name
now.



attribute myAttribute


I think this could be done as a struct, but I haven't
used this kind of attribute at all so not sure...

But what I'm thinking is:

struct myAttribute(Type) {
   Type value;
   alias value this;

   bool bNeedsAttention;
   @property void refresh(bool bRefresh) { bNeedsAttention = 
bRefresh; }

}

myAttribute!int thing;
thing.refresh = true;

and thing can be substituted for an int anywhere else.


Re: Proposal: user defined attributes

2012-03-16 Thread Manu
On 16 March 2012 16:51, Adam D. Ruppe  wrote:

> On Friday, 16 March 2012 at 14:11:35 UTC, Manu wrote:
>
>> Surely the term you're looking for here is @annotate(...) ?
>>
>
> Meh, I don't care that much about names. I went
> with "note" anticipating people would complain about
> @add_user_defined_attribute() being too long :)
>
>
>
>  What if you want to annotate with a variable?
>>
>
> That *might* work because a variable is an expression too.
> I'm not sure though. Will probably have to implement to
> know for sure.
>
> Of course, a constant can be represented as a struct
> for name and value:
>
> struct Description { string s; }
>
> @note(Description("yada yada yada")) int a;
>
>
>
>  Surely this is just as easy: @modulename.attribute int myThing;
>>
>
> Yeah, I think so. I remember this being a counterpoint
> last time we talked about it, but I don't recall the
> specific argument made.
>
>
>  Perhaps that's the key distinction between 'annotation' and a 'custom
>> attributes' .. an annotation this way is a shared compile time constant,
>> associating with its type info, as you suggest. A custom attribute is an
>> instance-specific association vontaining variable data.
>>
>
> Yeah, "annotation" might be the better word. That's
> what I want here, but too late to change the subject name
> now.
>
>
>  attribute myAttribute
>>
>
> I think this could be done as a struct, but I haven't
> used this kind of attribute at all so not sure...
>
> But what I'm thinking is:
>
> struct myAttribute(Type) {
>   Type value;
>   alias value this;
>
>   bool bNeedsAttention;
>   @property void refresh(bool bRefresh) { bNeedsAttention = bRefresh; }
> }
>
> myAttribute!int thing;
> thing.refresh = true;
>
> and thing can be substituted for an int anywhere else.
>

Interesting approach, how will that affect 'thing's type?


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe

Another argument against would be "can we do
this in the language today?"

And the answer is "sort of, but not really":

void a(@note(...) int arg) {}


You could perhaps do something like:

void a(int arg) {}
mixin("enum " ~ a.mangleof ~ "_arg = " ~ ...);

and then get the listing by looking at allMembers
and comparing the name... but, it gets messy
fast - the attribute is somewhat far from the declaration,
so I betcha it will get out of sync.


Getting the attribute on param 0 too would consist
of using stringof tricks to get the name, then mixing
it in to get that variable.


This isn't a proper tuple either - more care would be
needed to handle multiple notes.



So, you could make it work, but it is hideous, fragile,
and probably less useful even if you look past that.

I've seen some nice implementations of struct level annotations,
using mixin templates, but the killer feature for me, personally,
is putting it on function parameters as well.


I think the language addition (which breaks nothing existing
today; it is purely additive) is necessary to get something
generally useful, not just useful in a few cases.


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe

On Friday, 16 March 2012 at 15:10:06 UTC, Manu wrote:

Interesting approach, how will that affect 'thing's type?


It will strictly be myAttribute!int, but alias this
means that you can pass it anywhere an int is expected
too (and assign ints to it all the same).

Check it:

void cool(int a) {}
void main() {
myAttribute!int thing;
thing.refresh = true;

thing = 10; // we can assign ints to it, like if it was 
an int

assert(thing.bNeedsAttention); // should be unchanged

int a = thing; // no problem, thing is usable as an int
assert(a == 10);

cool(thing); // ditto
}



Re: Proposal: user defined attributes

2012-03-16 Thread Manu
On 16 March 2012 17:14, Adam D. Ruppe  wrote:

> On Friday, 16 March 2012 at 15:10:06 UTC, Manu wrote:
>
>> Interesting approach, how will that affect 'thing's type?
>>
>
> It will strictly be myAttribute!int, but alias this
> means that you can pass it anywhere an int is expected
> too (and assign ints to it all the same).
>
> Check it:
>
> void cool(int a) {}
> void main() {
>
>myAttribute!int thing;
>thing.refresh = true;
>
>thing = 10; // we can assign ints to it, like if it was an int
>assert(thing.bNeedsAttention); // should be unchanged
>
>int a = thing; // no problem, thing is usable as an int
>assert(a == 10);
>
>cool(thing); // ditto
> }
>

I can see that it might work nicely in very simple cases, but it could get
nasty in complex constructs. If some template tries to take the typeof for
instance, now I'm cloning the attributes functionality too, which I don't
think is desirable...


Re: Proposal: user defined attributes

2012-03-16 Thread Piotr Szturmaj

Adam D. Ruppe wrote:

On the ride over here today, I had a thought that
I think neatly solves the user defined attribute
question.

enum Serializable { yes, no }

@note(Serializable.yes) int a;


This is just enum. If you use struct or class attributes (like in C#) 
then direct @Struct(constructor args..) might be better.


Moreover, structs and classes may have special member which validates 
attribute target:


struct MyAttribute
{
template canAttach(alias Symbol)
{
// attribute is only valid on structs and
// may be used only once per symbol
enum canAttach = is(Symbol == struct) &&
 !__traits(hasNotes, Symbol);
}
}

It should be automatically evaluated by the compiler after attribute is 
attached.


Alternatively it may be written like this:

template validate(alias Symbol)
{
static assert(is(Symbol == struct), "MyAttribute must be used with 
structs");

}


We introduce two new things to the language:

1) the @note(expression) attribute. You can put
as many "notes" on a declaration as you want by
simply listing them.

The expression inside is appended to a list on
the declaration.

This would be valid on variables, functions,
function parameters, struct members, etc.

2) __traits(getNotes, decl). This returns a tuple
of all the note expressions.

foreach(i, exp; __traits(getNotes, a)) {
static assert(is(typeof(exp) == Serializable);
static assert(exp == Serializable.yes);
}


This is nice. Also it's base for library functions like hasNotes or 
getNotes!(Symbol, MyAttribute).



This simple extension to the language enables libraries,
using existing traits to navigate symbols, to get
additional information about things and implement it
however.

The lack of user defined attributes is D's biggest missed
opportunity right now, and I think this simple proposal
will plug that hole.


Yes, it's big drawback for serialization and data binding code.


Previous user-defined attribute proposals have had counter
arguments like these:

1) how do you define what is and is not a valid attribute?

Here, the answer is pretty simple: you can put whatever notes
you want on the thing. Whether the library uses it or not
is up to it.

It has to be a valid type - so the compiler will catch
typos and whatnot - but it doesn't have to be used unless
you ask for it.


It should be any user-defined type that may be used at compile-time. For 
example @UUID("...") should be available out of the box.



2) OK, how do you namespace things so different libraries don't
get different results?

That's where the beauty of the expression type comes in: D
already has namespaces. foo.Serializable != bar.Serializable,
so there's no conflict.

We simply declare types. The enum X {yes, no} pattern is already
common in Phobos, and is also the best way to express a bool condition
here. (Technically, @note(true) would compile, but it'd be much less
useful than declaring a name for the note too, with an enum.)

Name conflicts is a problem already solved by the language.


Yes, it should be possible to write @std.UUID("").


3) Can we have shared attributes, with declared names so people
know what to use in their own libraries?


Of course, for example consider a validating attribute "Flags":

@Flags
enum SomeFlags
{
a = 1,
b = 2,
c = 4,
d = 8
}

During attachment it would check if enum member's bits don't overlap.


Re: Proposal: user defined attributes

2012-03-16 Thread Andrei Alexandrescu

On 3/16/12 8:35 AM, Adam D. Ruppe wrote:

enum Serializable { yes, no }

@note(Serializable.yes) int a;

[...]

foreach(i, exp; __traits(getNotes, a)) {
static assert(is(typeof(exp) == Serializable);
static assert(exp == Serializable.yes);
}


So we have:

class A {
@note(Serializable.yes) int a;
...
}

vs. a hypothetical in-language solution:

class A {
int a;
mixin(note("a", Serializable.yes));
...
}

I wonder to what extent the in-language solution can be made to work.


Andrei


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe
On Friday, 16 March 2012 at 16:09:55 UTC, Andrei Alexandrescu 
wrote:
I wonder to what extent the in-language solution can be made to 
work.


It can sort of work, but it isn't very good.

(I thought you might say this too; check out this post:
http://forum.dlang.org/thread/bccwycoexxykfgxve...@forum.dlang.org#post-gmtawdmaihzgxnvezfrf:40forum.dlang.org 
)



In that other post, I talked about function parameters (which
is what I really want it for). The in-language solution for that
can only be made to work with a pile of fragile hacks.

But, even for functions, you just wrote:

int a;
mixin(note("a", Serializable.yes));

OK, that works... but what about:

int a() { return 0; }
mixin(note("a", Serializable.yes));


We're good so far... until:

int a() { return 0; }
int a(int b) { return 0; }
mixin(note("a", Serializable.yes)); // which a?


You could potentially solve that by using the mangle of
instead of the string, and doing an alias template rather
than passing a string directly, but I'm not sure if we actually
can in today's dmd (I don't even know how to refer to
the proper overload...)

Also, what if the declaration is anonymous? You could
still see it in reflection - a ParameterTypeTuple doesn't
care about names - but you couldn't annotate it this
way. I guess a workaround there would be giving it a
name like _param_0.



Moreover, the mixin adds some junk to the struct. If
you iterate over allMembers, will you see

  enum _note_a_serializable;

in there? If there's a consistent naming convention,
we could skip it (my web.d ignores everything with a
leading underscore, for example), but it is nevertheless
letting implementation details slip out in reflection.

Seeing how the whole point of this is to be used in reflection,
that's a case I think is likely to cause annoyance in practice.



The current language solution isn't really *bad* with enough
library help, but it isn't particularly *good* either and I
don't think it can be. I've tried a few things, and I still
see the lack of user annotations as D's biggest miss right now.


Re: Proposal: user defined attributes

2012-03-16 Thread Steven Schveighoffer
On Fri, 16 Mar 2012 09:35:54 -0400, Adam D. Ruppe  
 wrote:



On the ride over here today, I had a thought that
I think neatly solves the user defined attribute
question.

enum Serializable { yes, no }

@note(Serializable.yes) int a;


I thought @ was supposed to be a user-defined annotation.   
Otherwise, why did we introduce @syntax?


I'd rather see something like this:

@annotation serializable(bool x = true) {return x ? Serializable.yes :  
Serializable.no;}  // implicit auto


@serializable int a;
@serializable(false) int b;

Where annotations have to be CTFE-able (because they are constructed at  
compile-time)


-Steve


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe
On Friday, 16 March 2012 at 16:57:26 UTC, Steven Schveighoffer 
wrote:
I thought @ was supposed to be a user-defined 
annotation.  Otherwise, why did we introduce @syntax?


idk, to "reduce" the number of keywords or somethiny.

This is why I call it a mistake or missed opportunity
right now though: @property, @safe, @disable, @system,
and @trusted have already made a claim on the @syntax.

Now, we have to work around that, which is why I'm
thinking @note(expression) rather than @.


I'd rather see something like this:


I could live with that too, but I think it'd be harder
to make happen due to potential clashes with the current
thing @ is used for.


Re: Proposal: user defined attributes

2012-03-16 Thread Steven Schveighoffer
On Fri, 16 Mar 2012 13:36:42 -0400, Adam D. Ruppe  
 wrote:



On Friday, 16 March 2012 at 16:57:26 UTC, Steven Schveighoffer wrote:
I thought @ was supposed to be a user-defined annotation.   
Otherwise, why did we introduce @syntax?


idk, to "reduce" the number of keywords or somethiny.


Quote from TDPL (section 5.9.1 on page 156):

"Attributes, always introduced with @, are simple adornments specifying  
certain features for the symbol being defined.  Some attributes are  
recognized by the compiler; some are defined and used by the programmer  
alone."


I assumed this was true, and thought so even before TDPL came out.  See  
http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP6



This is why I call it a mistake or missed opportunity
right now though: @property, @safe, @disable, @system,
and @trusted have already made a claim on the @syntax.


I think those are just compiler-defined attributes.  They aren't keywords  
in the sense that the parser doesn't treat them as special.  They are just  
another type of symbol.



I could live with that too, but I think it'd be harder
to make happen due to potential clashes with the current
thing @ is used for.


meh, just don't use @safe, @property, @disable, @system, and @trusted.  I  
don't see a huge number of compiler-defined attributes springing up.  Nor  
do I see a huge number of library or user-defined ones springing up.


-Steve


Re: Proposal: user defined attributes

2012-03-16 Thread Andrej Mitrovic
On 3/16/12, Adam D. Ruppe  wrote:
> The current language solution isn't really *bad* with enough
> library help, but it isn't particularly *good* either and I
> don't think it can be. I've tried a few things, and I still
> see the lack of user annotations as D's biggest miss right now.

Yeah, but I would say if we had even better compile-time introspection
we could have the freedom to implement any number of annotation
implementations in library code. When you put something into the
language you have to depend on C++ hackers to implement and then
inevitably fix the upcoming bugs in the front-end (ICEs are an
annoying blocker), and there's always that issue where the devs are
against adding new features to an existing language feature. (say
annotations were implemented, soon enough someone is going to complain
it doesn't have enough functionality and that it needs to be
extended).

Personally I'd love it if we had more __traits and compile-time
introspection abilities.


Re: Proposal: user defined attributes

2012-03-16 Thread Adam D. Ruppe
On Friday, 16 March 2012 at 18:07:18 UTC, Steven Schveighoffer 
wrote:

Quote from TDPL (section 5.9.1 on page 156):


Huh. There's nothing I can see in the compiler that even
hints at this. The @ thing is just another storage class
as far as it's concerned right now.

Nor do I see a huge number of library or user-defined ones 
springing up.


Yeah.

I still really like my expression idea though, but
thinking about your strategy, we could say:

When you see @, if it is a compiler word after it,
parse it that way. Otherwise, try to get a function
call out of it.

Treat the function call as an enum and add it to the
list. Thus, it is CTFE, namespaced, etc. like normal.

The return value is appended to the declaration's
attribute expression list (so the end result is the same
as I was thinking.)


I'm pretty sure that'd work..


Re: Proposal: user defined attributes

2012-03-16 Thread Steven Schveighoffer
On Fri, 16 Mar 2012 14:33:37 -0400, Adam D. Ruppe  
 wrote:



On Friday, 16 March 2012 at 18:07:18 UTC, Steven Schveighoffer wrote:

Quote from TDPL (section 5.9.1 on page 156):


Huh. There's nothing I can see in the compiler that even
hints at this. The @ thing is just another storage class
as far as it's concerned right now.


Right, the user-defined portion is not implemented.




Nor do I see a huge number of library or user-defined ones springing up.


Yeah.

I still really like my expression idea though, but
thinking about your strategy, we could say:

When you see @, if it is a compiler word after it,
parse it that way. Otherwise, try to get a function
call out of it.


The way I'd like to see it work (and not being a compiler writer, I have  
no idea if/how this would work) is:


When you see @, call a CTFE function with that name.

The compiler defines intrinsic functions @property, @disable, etc.  which  
return intrinsic data types that get appended to the attribute list.  Then  
the compiler recognizes those data types in the attribute list when  
deciding how things should be compiled.


This might not be feasible given the current implementation, or how  
compilers are designed, I have no idea.



The return value is appended to the declaration's
attribute expression list (so the end result is the same
as I was thinking.)


Yes.  And I'd like to see the other intrinsic attributes appended (and  
queryable) as well.


What we also may need in the @annotation declaration is an alias of the  
thing being compiled (again, don't know how feasible this is)


for example:

@annotation property(alias sym)() { static assert(is(sym == function));  
return INTRINSIC.isProperty;}


Maybe that's going too far :)

-Steve


Re: Proposal: user defined attributes

2012-03-16 Thread Johannes Pfau
Am Fri, 16 Mar 2012 16:21:41 +0100
schrieb Piotr Szturmaj :

> > @note(Serializable.yes) int a;
> 
> This is just enum. If you use struct or class attributes (like in C#) 
> then direct @Struct(constructor args..) might be better.
> 
> 
+1

> > The expression inside is appended to a list on
> > the declaration.
> >
> > This would be valid on variables, functions,
> > function parameters, struct members, etc.
> >
> > 2) __traits(getNotes, decl). This returns a tuple
> > of all the note expressions.
> >
> > foreach(i, exp; __traits(getNotes, a)) {
> > static assert(is(typeof(exp) == Serializable);
> > static assert(exp == Serializable.yes);
> > }
> 
> This is nice. Also it's base for library functions like hasNotes or 
> getNotes!(Symbol, MyAttribute).
+1

> > 1) how do you define what is and is not a valid attribute?
> >
> 
> It should be any user-defined type that may be used at compile-time.
> For example @UUID("...") should be available out of the box.

Or we could add a @attribute attribute:

@attribute struct Test
{
this(int a) {}...
}

@Test(99)
string someTestVal;

> > 2) OK, how do you namespace things so different libraries don't
> > get different results?
> >
> > That's where the beauty of the expression type comes in: D
> > already has namespaces. foo.Serializable != bar.Serializable,
> > so there's no conflict.
> >
> > We simply declare types. The enum X {yes, no} pattern is already
> > common in Phobos, and is also the best way to express a bool
> > condition here. (Technically, @note(true) would compile, but it'd
> > be much less useful than declaring a name for the note too, with an
> > enum.)
> >
> > Name conflicts is a problem already solved by the language.
> 
> Yes, it should be possible to write @std.UUID("").
> 
And all normal import rules should work for user defined attributes as
well (renamed imports, static imports, ...).




Re: Proposal: user defined attributes

2012-03-16 Thread Kapps
On Friday, 16 March 2012 at 16:09:55 UTC, Andrei Alexandrescu 
wrote:

So we have:

class A {
@note(Serializable.yes) int a;
...
}

vs. a hypothetical in-language solution:

class A {
int a;
mixin(note("a", Serializable.yes));
...
}

I wonder to what extent the in-language solution can be made to 
work.



Andrei


This gets to an unreasonable amount of noise and complexity. 
First, you have the issue of using mixins. Using mixins is quite 
ugly. It's very tool unfriendly. It's not easily readable. It can 
mess up line numbers. It may or may not be limited in situations 
such as with parameters.


In language solutions should be preferred for many things, but 
ultimately, not everything is a nail to hammer.


Ultimately, I'd like to see being able to use any CTFE capable 
struct/class for an attribute with a constructor, ideally with 
access to the symbol it's defined on. This allows things like (if 
my unchecked code was correct):


@attribute struct WebForm {
string FormName;
this(string FormName) {
this.FormName = FormName;
static assert(is(typeof(Symbol) : struct));
static assert(__traits(getAllMembers, Symbol).length > 0);
// TODO: Make sure at least one member set to 
Browsable(true).

}
}

@attribute struct Validate {
string Pattern;
this(string Pattern) {
this.Pattern = Pattern;
static assert(isValidRegex(Pattern));
}
}

@WebForm("Account");
@PostTo("Services/CreateAccount")
@SecureOnly(true)
struct CreateAccountForm {

@Description("The name of your account. Must be between 3 and 
12 letters.");

@Validate(r"\w{3,12}")
string Username;

@Validate(r"\w+@\w+.\w+");
@Description("The email address to associate with this 
account.");

string Email;

}

While it's a bit of boiler plate to create the library and 
attributes, you only need to do it once. Then you can make a very 
nice form that automatically validates fields both clientside 
(where JS and/or CSS3 is supported) and serverside (when posted 
to Services/CreateAccount). You can verify a bunch of things at 
compile-time, including that the service exists or that the 
validation contains valid regex. And best of all, it's actually 
readable unlike if you went with a mixin approach. You would end 
up having 7 random mixins in that above form, and have to 
manually check each one to see if it's creating code or just 
creating an attribute. This way, you can see the @ and know it's 
an attribute immediately.


Another thing that doesn't come up yet but may in the future: 
reflection. It seems worrying to have random mixins adding 
reflection info, as that's a job for the compiler. It knows about 
when reflection is enabled, it knows how much it needs to 
generate, if things exist after optimization, etc. There's no 
point leaving that to a mixin and having to keep it in sync with 
the compiler. This way though, there's no need. The reflection 
data would just have an annotations property that can be accessed.


Re: Proposal: user defined attributes

2012-03-16 Thread Andrej Mitrovic
On 3/17/12, Kapps  wrote:
> @WebForm("Account");
> @PostTo("Services/CreateAccount")
> @SecureOnly(true)
> struct CreateAccountForm {

That kind of turns D from a structural to a declarative language. :p


Re: Proposal: user defined attributes

2012-03-16 Thread Kapps

On Saturday, 17 March 2012 at 00:54:02 UTC, Andrej Mitrovic wrote:

On 3/17/12, Kapps  wrote:

@WebForm("Account");
@PostTo("Services/CreateAccount")
@SecureOnly(true)
struct CreateAccountForm {


That kind of turns D from a structural to a declarative 
language. :p


Web design is quite a declarative thing. :) The code is already 
written for you, why bother writing it again instead of just 
writing it once and passing along essentially parameters to it.


Anywho, something like that is a somewhat extreme case. Basic 
things include @serializable or @notserialized (or 
@serialized(false)). With the topic of dynamic/scripting 
languages, other things can include @scripted to indicate a 
method or class can be accessed from the script, or 
@scripted(Security.low) to indicate user scripts can access it 
and not just game scripts. This prevents having to make annoying 
bindings and communicate what's passed in to the script compiler. 
Instead, you can find out everything that can be passed in at 
compile-time, and upon script compilation you can verify the 
script has access to all of these methods, then statically call 
them without any of the performance hit you would normally have 
by using scripting, yet with the safety.


Re: Proposal: user defined attributes

2012-03-16 Thread Alvaro

El 16/03/2012 14:35, Adam D. Ruppe escribió:



We introduce two new things to the language:

1) the @note(expression) attribute. You can put
as many "notes" on a declaration as you want by
simply listing them.




I like that.

I learned about annotations a couple years ago in two contexts:

- Web Services in Java and C#
- Hibernate in Java

They come very handy and are hard to beat with current language features.

[WebService]
public class Service : WebService
{
[WebMethod]
public string helloWorld() {
return "Hello World";
}
}

What coult be a similar D with annotations?:

@note(WebService)
class Service : WebService
{
@note(WebMethod)
string helloWorld() {
return "Hello World";
}
}

and have some CTFE stuff generate the magic?


Re: Proposal: user defined attributes

2012-03-17 Thread Manu
On 17 March 2012 02:53, Andrej Mitrovic  wrote:

> On 3/17/12, Kapps  wrote:
> > @WebForm("Account");
> > @PostTo("Services/CreateAccount")
> > @SecureOnly(true)
> > struct CreateAccountForm {
>
> That kind of turns D from a structural to a declarative language. :p
>

And that's awesome in many situations! :)

This also maps really well to games/tools/editors/script bindings. C# has
this, and it's an invaluable language feature. It adds so much simplicity
to the tools code.


Re: Proposal: user defined attributes

2012-03-17 Thread Gor Gyolchanyan
What we're talking about here is subject-oriented programming: having
the attributes get enclosed into objects, rather then objects
enclosing attributes. And this is extremely useful, IMO.

On Sat, Mar 17, 2012 at 1:23 PM, Manu  wrote:
> On 17 March 2012 02:53, Andrej Mitrovic  wrote:
>>
>> On 3/17/12, Kapps  wrote:
>> > @WebForm("Account");
>> > @PostTo("Services/CreateAccount")
>> > @SecureOnly(true)
>> > struct CreateAccountForm {
>>
>> That kind of turns D from a structural to a declarative language. :p
>
>
> And that's awesome in many situations! :)
>
> This also maps really well to games/tools/editors/script bindings. C# has
> this, and it's an invaluable language feature. It adds so much simplicity to
> the tools code.



-- 
Bye,
Gor Gyolchanyan.


Re: Proposal: user defined attributes

2012-03-17 Thread Jacob Carlborg

On 2012-03-16 14:35, Adam D. Ruppe wrote:

On the ride over here today, I had a thought that
I think neatly solves the user defined attribute
question.


I would love to have user defined attributes in D but I'm not completely 
like your approach. I would go with something more like Java 
annotations. This is how I would like user defined attributes to work.


Attributes can be applied to most declarations like: classes, fields, 
variables, functions, parameters and so on. Attributes are used with the 
following syntax:


@foo(key = "value", key2 = "value2) class Bar {}

"foo" is the name of the attribute. In the parentheses is a key-value 
list passed to the attribute. The values can be of any type available at 
compile time.


Attributes are defined as follows:

We add a new attribute called "@annotation" or "@attribute". This 
attribute is applied to a class or struct to make it an attribute:


@attribute class foo
{
string key;
string key2;
}

The keys the attribute accepts are declared in the class as either 
fields or methods (haven't decided yet). It's perfectly fine to have an 
attribute accepting no values which doesn't have to declare any keys:


@attribute class bar {}

If an attribute only accepts one value the name of the value needs to be 
"value":


@attribute class fooBar
{
string value;
}

This allows to not have to specify the key when passing a value to the 
attribute:


@fooBar("asd") class Foo {}

Accessing information about attribute should be possible both during 
compile time and runtime. At compile time "__traits" can be used:


__traits(hasAttribute, bar, Foo); // returns true if the attribute "bar" 
as been applied to "Foo"


__traits(getAttribute, bar, key, Foo); // returns the value of the key "key"

This is all very similar to how it works in Java:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/annotations.html

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/16/2012 7:11 AM, Manu wrote:

attribute myAttribute
{
   this(int something);

   bool bNeedsAttention;

   property void refresh(bool bRefresh) { bNeedsAttention = bRefresh; }
}

@myAttribute(10) int thing;

thing.refresh = true;


Under the hood, where would that per-instance data be stored?

Compile-time annotations can be stored internally to the compiler, but 
per-instance runtime data? How is it connected to the instance? When is it 
constructed and destroyed?


Re: Proposal: user defined attributes

2012-03-17 Thread Manu
On 17 March 2012 21:56, Walter Bright  wrote:

> On 3/16/2012 7:11 AM, Manu wrote:
>
>> attribute myAttribute
>> {
>>   this(int something);
>>
>>   bool bNeedsAttention;
>>
>>   property void refresh(bool bRefresh) { bNeedsAttention = bRefresh; }
>> }
>>
>> @myAttribute(10) int thing;
>>
>> thing.refresh = true;
>>
>
> Under the hood, where would that per-instance data be stored?
>
> Compile-time annotations can be stored internally to the compiler, but
> per-instance runtime data? How is it connected to the instance? When is it
> constructed and destroyed?
>

In Java+C# it just lives in the class somewhere. Put it right beside the
attributed member, or maybe separate them into an attribute section at the
end of the class (to preserve structural layout). Construct along with the
class, I suppose the moment would be after member initialisation, but
before the constructor executes.
I wonder if it should only be allowed on classes/class members... adding
hidden data to a 'struct' almost defeats the purpose. Java doesn't have
'struct', so no problem. I wonder what C# does exactly...


Re: Proposal: user defined attributes

2012-03-17 Thread Manu
On 17 March 2012 23:52, Manu  wrote:

> On 17 March 2012 21:56, Walter Bright  wrote:
>
>> On 3/16/2012 7:11 AM, Manu wrote:
>>
>>> attribute myAttribute
>>> {
>>>   this(int something);
>>>
>>>   bool bNeedsAttention;
>>>
>>>   property void refresh(bool bRefresh) { bNeedsAttention = bRefresh; }
>>> }
>>>
>>> @myAttribute(10) int thing;
>>>
>>> thing.refresh = true;
>>>
>>
>> Under the hood, where would that per-instance data be stored?
>>
>> Compile-time annotations can be stored internally to the compiler, but
>> per-instance runtime data? How is it connected to the instance? When is it
>> constructed and destroyed?
>>
>
> In Java+C# it just lives in the class somewhere. Put it right beside the
> attributed member, or maybe separate them into an attribute section at the
> end of the class (to preserve structural layout). Construct along with the
> class, I suppose the moment would be after member initialisation, but
> before the constructor executes.
> I wonder if it should only be allowed on classes/class members... adding
> hidden data to a 'struct' almost defeats the purpose. Java doesn't have
> 'struct', so no problem. I wonder what C# does exactly...
>

I tend to think of 'struct's as 'passive', and compile-time annotations
would provide me with every use case I can imagine for my own purposes in
the case of structs. classes seem far more likely to need stateful
attributes.


Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/17/2012 2:55 PM, Manu wrote:

I tend to think of 'struct's as 'passive', and compile-time annotations would
provide me with every use case I can imagine for my own purposes in the case of
structs. classes seem far more likely to need stateful attributes.


I currently find the notion of runtime attribute state to be fraught with all 
kinds of unresolved and murky issues with no obvious answer:


1. construction/destruction
2. shared
3. const/immutable
4. thread locality
5. allocated statically or dynamically
6. shared library issues?

If the attribute is code, when does that code get run?

1. on initialization
2. on termination
3. on read
4. on write
5. what about read/write?


Re: Proposal: user defined attributes

2012-03-17 Thread Manu
On 18 March 2012 03:10, Walter Bright  wrote:

> On 3/17/2012 2:55 PM, Manu wrote:
>
>> I tend to think of 'struct's as 'passive', and compile-time annotations
>> would
>> provide me with every use case I can imagine for my own purposes in the
>> case of
>> structs. classes seem far more likely to need stateful attributes.
>>
>
> I currently find the notion of runtime attribute state to be fraught with
> all kinds of unresolved and murky issues with no obvious answer:
>
> 1. construction/destruction
>

After initialisation, before construction.

2. shared
>

How is this any different than for the class its self?

3. const/immutable
>

Inherit these properties.

4. thread locality
>

Same as class.

5. allocated statically or dynamically
>

I'd say dynamically if restricted to classes, but some suggested the syntax
'@attribute struct/class MyAttribute { }', which could clarify the intent.

6. shared library issues?
>

If extern(D), then there should be no problems. If extern(C), then the
attributes would just appear like structure members. Assuming the layout
was documented (ie, in-order of appearance, at the end of the class), C/C++
could include them at the end of the class definition, and access them
directly as if usual classes. All that would be lost is the implicit
(compile time) association between the attribute and its associated class
member.
I don't think it's fair to expect a novel language feature to be supported
by C/C++ though.


If the attribute is code, when does that code get run?
>
> 1. on initialization
> 2. on termination
> 3. on read
> 4. on write
> 5. what about read/write?
>

I might go and read up on C# more thoroughly and get back to you... maybe
others here are already more familiar with C#'s attribute management?
I'm sure C# already answers all these questions. It has precisely the same
set of issues associated.


Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/17/2012 6:39 PM, Manu wrote:

I'm sure C# already answers all these questions. It has precisely the same set
of issues associated.


C# doesn't have RAII, immutable, nor the notion of threadlocal/shared types.


Re: Proposal: user defined attributes

2012-03-17 Thread Manu
On 18 March 2012 03:48, Walter Bright  wrote:

> On 3/17/2012 6:39 PM, Manu wrote:
>
>> I'm sure C# already answers all these questions. It has precisely the
>> same set
>> of issues associated.
>>
>
> C# doesn't have RAII, immutable, nor the notion of threadlocal/shared
> types.
>

C# has immutable. How does RAII cause a problem here?
The threadlocal/shared stuff shouldn't be a problem, since the attribute
instances are contained by the class its self, it just has the same
locality properties. Can you imagine a case where that would be problematic?


Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/17/2012 7:04 PM, Manu wrote:

On 18 March 2012 03:48, Walter Bright mailto:newshou...@digitalmars.com>> wrote:

On 3/17/2012 6:39 PM, Manu wrote:

I'm sure C# already answers all these questions. It has precisely the
same set
of issues associated.


C# doesn't have RAII, immutable, nor the notion of threadlocal/shared types.


C# has immutable.


No, it does not.


How does RAII cause a problem here?


Generally, supporting it tends to permeate the semantics of the language. Simple 
things like copying a value onto the parameter stack entail all kinds of issues.



The threadlocal/shared stuff shouldn't be a problem, since the attribute
instances are contained by the class its self, it just has the same locality
properties. Can you imagine a case where that would be problematic?


If it's shared, how is access to the data controlled if multiple threads access 
it at the same time?




Re: Proposal: user defined attributes

2012-03-17 Thread Kapps

On Sunday, 18 March 2012 at 01:48:07 UTC, Walter Bright wrote:

On 3/17/2012 6:39 PM, Manu wrote:
I'm sure C# already answers all these questions. It has 
precisely the same set

of issues associated.


C# doesn't have RAII, immutable, nor the notion of 
threadlocal/shared types.


It has threadlocal using the [ThreadLocal] attribute which gets 
implemented by the compiler.


In C#, all attributes live inside the TypeInfo/MethodInfo/etc for 
the class/struct/method/field/parameter. I don't see this being a 
problem. I can't think of good use cases where an 
attribute/annotation should be per-instance at all, particularly 
with the compile-time power that D has, whereas C# does not have 
any. Honestly, most uses of attributes in D would be done at 
compile-time, and I think that's acceptable until/if runtime 
reflection is put in. If it is needed, it can live inside 
TypeInfo/MethodInfo, but is (imo) absolutely not needed on a 
per-instance basis. This is the job of fields or interfaces.


Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/17/2012 8:04 PM, Kapps wrote:

It has threadlocal using the [ThreadLocal] attribute which gets implemented by
the compiler.


That's a storage class, not a type constructor. In D, threadlocal/shared is a 
difference in the type.



In C#, all attributes live inside the TypeInfo/MethodInfo/etc for the
class/struct/method/field/parameter. I don't see this being a problem. I can't
think of good use cases where an attribute/annotation should be per-instance at
all, particularly with the compile-time power that D has, whereas C# does not
have any. Honestly, most uses of attributes in D would be done at compile-time,
and I think that's acceptable until/if runtime reflection is put in. If it is
needed, it can live inside TypeInfo/MethodInfo, but is (imo) absolutely not
needed on a per-instance basis. This is the job of fields or interfaces.


I also do not get why per-instance attributes even exist, as I agree that's what 
fields are for.


Re: Proposal: user defined attributes

2012-03-17 Thread Adam D. Ruppe

Walter, how do you feel about the compile time
annotation list?

I looked at implementing it, and it is a little
more involved than I thought (mainly in changing
parse.c to treat @ things as more than just storage
classes), but still not terrible.


Re: Proposal: user defined attributes

2012-03-17 Thread F i L

Walter Bright wrote:
I also do not get why per-instance attributes even exist, as I 
agree that's what fields are for.


Attributes are per-type (type properties, methods, etc), not 
per-instance, and only accessible (in C#) through type reflection 
(to my knowledge). According to 
http://msdn.microsoft.com/en-us/library/z919e8tw(v=vs.80).aspx 
attribute objects aren't constructed until reflected upon. I 
think attributes in combination with D's templates would be very 
useful:


@attribute class Cool
{
bool isCool;
this(bool cool)
{
isCool = cool;
}
}

class CoolClass(bool cool)
{
@CoolType(cool);
int type;
}

void main()
{
auto cc = new CoolClass!true();
if (cc.type@Cool.isCool) { // (new Cool(true)).isCool
// Do something cool...
}
}

Or, if @attributes could be applied to *any* type (enums, 
structs, variables, etc..), we could write this more simply:


@attribute bool isCool;

class CoolClass(bool cool)
{
@isCool = cool;
int type;
}

void main()
{
auto cc = new CoolClass!true();
if (cc.type@isCool) { // true
// Do something cool...
}
}

and of course, the compiler could make use of attribute metadata 
during codegen. Things like Garbage Collection and memory 
compaction attributes come to mind:


class MemoryPool
{
@GC.DontScan void*[] pool;
@Int.Fast int index; // replace stdint
}

Also, aliasing could be possible:

   @Int.Fast alias int intf;
   @Int.Least alias int intl;


Re: Proposal: user defined attributes

2012-03-17 Thread F i L

F i L wrote:

class CoolClass(bool cool)
{
@CoolType(cool);
int type;
}


typo **@Cool(cool);

plus, I think a better syntax for attributes might be to have an 
attribute keyword for definitions and only use "@" for 
application:


attribute struct CoolType { ... }
attribute bool isCool;

@CoolType @(isCool = true) string coolText;



Re: Proposal: user defined attributes

2012-03-17 Thread Walter Bright

On 3/17/2012 9:12 PM, F i L wrote:

Walter Bright wrote:

I also do not get why per-instance attributes even exist, as I agree that's
what fields are for.


Attributes are per-type (type properties, methods, etc), not per-instance, and
only accessible (in C#) through type reflection (to my knowledge). According to
http://msdn.microsoft.com/en-us/library/z919e8tw(v=vs.80).aspx attribute objects
aren't constructed until reflected upon.


My impression is it is just obfuscation around a simple lazy initialization 
pattern.

While I can see the abstraction usefulness of compile time attribute metadata, I 
am having a hard time seeing what the gain is with runtime attributes over more 
traditional techniques.


Re: Proposal: user defined attributes

2012-03-17 Thread F i L

Walter Bright wrote:
My impression is it is just obfuscation around a simple lazy 
initialization pattern.


While I can see the abstraction usefulness of compile time 
attribute metadata, I am having a hard time seeing what the 
gain is with runtime attributes over more traditional 
techniques.


I'm not sure exactly what you mean by runtime attributes. Do you 
mean the ability to reflect upon attributes at runtime? In that 
case, there's two  benefits I can think of over "traditional" 
member data: Instance memory (attributes are create at 
reflection), and reusable metadata packages (similar to how you 
might use mixin templates only with less noise and reflection 
capabilities).


Re: Proposal: user defined attributes

2012-03-18 Thread Walter Bright

On 3/17/2012 10:01 PM, F i L wrote:

Walter Bright wrote:

My impression is it is just obfuscation around a simple lazy initialization
pattern.

While I can see the abstraction usefulness of compile time attribute metadata,
I am having a hard time seeing what the gain is with runtime attributes over
more traditional techniques.


I'm not sure exactly what you mean by runtime attributes. Do you mean the
ability to reflect upon attributes at runtime?


I mean there is modifiable-at-runtime, instance-specific data.


In that case, there's two
benefits I can think of over "traditional" member data: Instance memory
(attributes are create at reflection),


Lazy initialization is a standard pattern. No special language features are 
needed for it.



and reusable metadata packages (similar
to how you might use mixin templates only with less noise and reflection
capabilities).


Sounds like a garden variety user-defined data type.

Again, I am just not seeing the leap in power with this. It's a mystery to me 
how a user defined "attribute class" is different in any way from a user defined 
class, and what advantage special syntax gives a standard pattern for lazy 
initialization, and why extra attribute fields can't be just, well, fields.


Re: Proposal: user defined attributes

2012-03-18 Thread Walter Bright

On 3/17/2012 8:12 PM, Adam D. Ruppe wrote:

Walter, how do you feel about the compile time
annotation list?


I feel it has merit, but I think it is possibly more complex than necessary.

Note that I have never used user defined attributes, so I don't have experience 
to guide me on this.




Re: Proposal: user defined attributes

2012-03-18 Thread F i L

Walter Bright wrote:

I mean there is modifiable-at-runtime, instance-specific data.


In C#, no there isn't. Attributes are simply objects constructed 
(when gotten) from an Entity's metadata. No memory is stored 
per-instance unless you manage the objects manually:


class A : Attribute { public string s = "Default"; }

[TestA] class C {}

static void Main()
{
// The line below is equivalent to: var a = new A();
// except that it's construction is defined by
// metadata stored in type C.
var a = typeof(C).GetCustomAttributes(true)[0] as A;
a.s = "Modification";
Console.WriteLine(a.s); // prints "Modification"

// Therefor...
var b = typeof(C).GetCustomAttributes(true)[0] as A;
Console.WriteLine(b.s); // prints "Default"
}


In that case, there's two
benefits I can think of over "traditional" member data: 
Instance memory

(attributes are create at reflection),


Lazy initialization is a standard pattern. No special language 
features are needed for it.


I see how my statements (and code examples) where confusing. I 
meant that no attribute data is stored per-instance at all 
(unless traditionally done so), and that attribute objects are 
simply create in-place at the point of access. So to clarify my 
previous code a bit:


attribute class A { string i = "Default"; }

@A class C { A a; }

void main()
{
auto a = C@A; // create new A based on C
assert(is(typeof(a) : A));

// alternatively you could do:
auto c = new C();
auto a = c@A; // same as: typeof(c)@A

c.a = c@A; // explicitly store attribute
}

Note: Might want to use the "new" keyword with class type 
attributes (auto a = new C@A), but the idea's there. Plus, I 
think that looks a lot better than the C# version.



and reusable metadata packages (similar
to how you might use mixin templates only with less noise and 
reflection capabilities).


Sounds like a garden variety user-defined data type.


It is. Only it's a data type who's construction values are stored 
in metadata (per entity), and therefor can be used at both 
compile and run times. By per-entity I mean for each unique Type, 
Type member, Sub-Type, etc.


I don't know of any existing D idiom that is capable of what I 
presented. If there is, I would like to know. Here's the closest 
I can think of:


mixin template CoolInt(bool cool, string name)
{
mixin("enum bool " ~ name ~ "_isCool = cool;");
mixin("int " ~ name ~ ";");
}

class CoolClass
{
mixin CoolInt!(true, "a");
mixin CoolInt!(false, "b");
}

void main()
{
auto c = new CoolClass();
writeln(c.a_isCool); // true
writeln(c.b_isCool); // false
}

which, aside from noise, is great for runtime reflection, but 
it's completely useless (i think) for the compiler because the 
variables are created through arbitrary strings. Plus, I don't 
know how you'd store anything but simple variables, which more 
complex data would require a lot of _variables.


Re: Proposal: user defined attributes

2012-03-18 Thread F i L

F i L wrote:
Plus, I don't know how you'd store anything but simple 
variables, which more complex data would require a lot of 
_variables.


I found a way:

mixin template Attribute(
  string type,
  string name,
  string attr,
  Params...)
{
mixin (type ~ " " ~ name ~ ";");
mixin (
"auto " ~ name ~ "_" ~ attr ~ "()" ~
"{ return new " ~ attr ~ "(Params); }"
);
}

class Cool
{
string s;
this(string s)
{
this.s = s;
}
}

class CoolClass
{
mixin Attribute!("int", "a", "Cool", "Heh");
mixin Attribute!("int", "b", "Cool", "Sup");
}

void main()
{
auto c = new CoolClass();
writeln(c.a, ", ", c.b); // 0, 0
writeln(c.a_Cool().s); // Heh
writeln(c.b_Cool().s); // Sup
}



Re: Proposal: user defined attributes

2012-03-18 Thread Tove

On Sunday, 18 March 2012 at 10:25:20 UTC, F i L wrote:

F i L wrote:
class CoolClass
{
mixin Attribute!("int", "a", "Cool", "Heh");
mixin Attribute!("int", "b", "Cool", "Sup");
}

void main()
{
auto c = new CoolClass();
writeln(c.a, ", ", c.b); // 0, 0
writeln(c.a_Cool().s); // Heh
writeln(c.b_Cool().s); // Sup
}


Is it not possible to alias a mixin to just one letter, and then 
use it to have any syntax we want... something like this:


x("@attribute(Serializable.yes) int a");




Re: Proposal: user defined attributes

2012-03-18 Thread F i L

On Sunday, 18 March 2012 at 10:38:19 UTC, Tove wrote:

On Sunday, 18 March 2012 at 10:25:20 UTC, F i L wrote:

F i L wrote:
class CoolClass
{
   mixin Attribute!("int", "a", "Cool", "Heh");
   mixin Attribute!("int", "b", "Cool", "Sup");
}

void main()
{
   auto c = new CoolClass();
   writeln(c.a, ", ", c.b); // 0, 0
   writeln(c.a_Cool().s); // Heh
   writeln(c.b_Cool().s); // Sup
}


Is it not possible to alias a mixin to just one letter, and 
then use it to have any syntax we want... something like this:


x("@attribute(Serializable.yes) int a");


Sure, but there's still the issue of using attributes for 
codegen. For instance compare:


struct Test {
@GC.NoScan int value;
}

to, the current:

struct Test {
int value;
this() { GC.setAttr(&value, NO_SCAN); }
}

How can we do that with mixin templates? If attributes where a 
language type the compiler could exploit in a consistent way, It 
would be *trivial* describing this behavior in a declarative way.


Re: Proposal: user defined attributes

2012-03-18 Thread F i L

F i L wrote:

struct Test {
int value;
this() { GC.setAttr(&value, NO_SCAN); }
}


bleh, should be...

struct Test {
int value;
this(int v) { GC.setAttr(&value, GC.BlkAttr.NO_SCAN); }
}

Or something like that. I've never actually set GC attributes 
before.


But this also raises another issue. Structs don't have default 
constructors, so applying NoScan attributes (by default) is, to 
my knowledge, impossible. Whereas it could (?) be possible 
through attributes.


Re: Proposal: user defined attributes

2012-03-18 Thread Tove

On Sunday, 18 March 2012 at 10:50:14 UTC, F i L wrote:

x("@attribute(Serializable.yes) int a");


Sure, but there's still the issue of using attributes for 
codegen. For instance compare:


struct Test {
@GC.NoScan int value;
}

to, the current:

struct Test {
int value;
this() { GC.setAttr(&value, NO_SCAN); }
}

How can we do that with mixin templates? If attributes where a 
language type the compiler could exploit in a consistent way, 
It would be *trivial* describing this behavior in a declarative 
way.


Hmm... well if the x declarations store all NoScan objects in a 
collection, it could be injected into the constructor token 
stream later...


x!("@GC.NoScan int value;");

// modified by x to insert a foreach with GC.setAttr
x!(q{this() {/* foreach(...) GC.setAttr(...); */ });

But I guess one lose the opportunity for some compile time 
magic... in a more efficient way than exposed by the GC.settAttr 
API.(just pure speculation, I don't have sufficient knowledge of 
the internal representation of our GC design.).






Re: Proposal: user defined attributes

2012-03-18 Thread Manu
On 18 March 2012 05:04, Kapps  wrote:

> On Sunday, 18 March 2012 at 01:48:07 UTC, Walter Bright wrote:
>
>> On 3/17/2012 6:39 PM, Manu wrote:
>>
>>> I'm sure C# already answers all these questions. It has precisely the
>>> same set
>>> of issues associated.
>>>
>>
>> C# doesn't have RAII, immutable, nor the notion of threadlocal/shared
>> types.
>>
>
> It has threadlocal using the [ThreadLocal] attribute which gets
> implemented by the compiler.
>
> In C#, all attributes live inside the TypeInfo/MethodInfo/etc for the
> class/struct/method/field/**parameter. I don't see this being a problem.
> I can't think of good use cases where an attribute/annotation should be
> per-instance at all, particularly with the compile-time power that D has,
> whereas C# does not have any. Honestly, most uses of attributes in D would
> be done at compile-time, and I think that's acceptable until/if runtime
> reflection is put in. If it is needed, it can live inside
> TypeInfo/MethodInfo, but is (imo) absolutely not needed on a per-instance
> basis. This is the job of fields or interfaces.
>

I think that's a fair call. I wonder why Java feels the need for stateful
attributes.
I have made extensive use of java attributes that have been stateful.
Java's persistence api's rely on stateful attributes a lot, but I think
that can be done in other ways in D.

Compile-time attributes sound like a great start, it's much simpler. But
they do need to be able to 'do stuff', ie, add some property/method to a
field (using the field its self as the context pointer), not just simply
'tag' it.


Re: Proposal: user defined attributes

2012-03-18 Thread F i L

Tove wrote:
Hmm... well if the x declarations store all NoScan objects in a 
collection, it could be injected into the constructor token 
stream later...


x!("@GC.NoScan int value;");

// modified by x to insert a foreach with GC.setAttr
x!(q{this() {/* foreach(...) GC.setAttr(...); */ });


But if x!() pumps out a constructor, how do you add multiple 
attributes with @GC.NoScan? The constructors would collide.





Re: Proposal: user defined attributes

2012-03-18 Thread Tove

On Sunday, 18 March 2012 at 12:10:23 UTC, F i L wrote:

Tove wrote:
Hmm... well if the x declarations store all NoScan objects in 
a collection, it could be injected into the constructor token 
stream later...


x!("@GC.NoScan int value;");

// modified by x to insert a foreach with GC.setAttr
x!(q{this() {/* foreach(...) GC.setAttr(...); */ });


But if x!() pumps out a constructor, how do you add multiple 
attributes with @GC.NoScan? The constructors would collide.


1. x! would parse all decls at compile time...
2. all attributes that need to modify the constructor is inserted 
at the points where the x! enabled constructors are 
declared/implemented...


x!("@GC.NoScan @GC.Hot @attribute(Serializable.yes) int value;");

x!(q{this()
{
  /* everything from 'x' is auto inserted here */
  my;
  normal;
  constructor;
  tokens;
});



Re: Proposal: user defined attributes

2012-03-18 Thread F i L

Tove wrote:

1. x! would parse all decls at compile time...
2. all attributes that need to modify the constructor is 
inserted at the points where the x! enabled constructors are 
declared/implemented...


x!("@GC.NoScan @GC.Hot @attribute(Serializable.yes) int 
value;");


x!(q{this()
{
  /* everything from 'x' is auto inserted here */
  my;
  normal;
  constructor;
  tokens;
});


I see, that would work. But why not just build this same 
operation into the compiler so the definition syntax is the same 
as usual. The mixin's are powerful but a bit ugly. Not to mention 
not IDE parser on the planet is going to be able to figure out 
all that to give you intelligent code-completion.




Re: Proposal: user defined attributes

2012-03-18 Thread Tove

On Sunday, 18 March 2012 at 12:39:19 UTC, F i L wrote:

Tove wrote:

1. x! would parse all decls at compile time...
2. all attributes that need to modify the constructor is 
inserted at the points where the x! enabled constructors are 
declared/implemented...


x!("@GC.NoScan @GC.Hot @attribute(Serializable.yes) int 
value;");


x!(q{this()
{
 /* everything from 'x' is auto inserted here */
 my;
 normal;
 constructor;
 tokens;
});


I see, that would work. But why not just build this same 
operation into the compiler so the definition syntax is the 
same as usual. The mixin's are powerful but a bit ugly. Not to 
mention not IDE parser on the planet is going to be able to 
figure out all that to give you intelligent code-completion.


Yes, I was thinking along these lines... what would be the 
absolutely bare minimum needed support this from the compiler to 
make this "scheme" look first class?


what if... the compiler encounters an unknown @token then it 
would delegate the parsing to a library implementation... which 
basically would do the above, but it would be hidden from the 
user... this way we would get a 0 effort(from the perspective of 
the compiler) and extensible syntax in library covering all 
future needs.




Re: Proposal: user defined attributes

2012-03-18 Thread Walter Bright

On 3/18/2012 2:47 AM, F i L wrote:

Walter Bright wrote:

I mean there is modifiable-at-runtime, instance-specific data.


In C#, no there isn't. Attributes are simply objects constructed (when gotten)
from an Entity's metadata. No memory is stored per-instance unless you manage
the objects manually:

class A : Attribute { public string s = "Default"; }

[TestA] class C {}

static void Main()
{
// The line below is equivalent to: var a = new A();
// except that it's construction is defined by
// metadata stored in type C.
var a = typeof(C).GetCustomAttributes(true)[0] as A;
a.s = "Modification";
Console.WriteLine(a.s); // prints "Modification"
// Therefor...
var b = typeof(C).GetCustomAttributes(true)[0] as A;
Console.WriteLine(b.s); // prints "Default"
}


Which looks indistinguishable from modifiable at runtime, instance specific 
data.



Lazy initialization is a standard pattern. No special language features are
needed for it.


I see how my statements (and code examples) where confusing. I meant that no
attribute data is stored per-instance at all (unless traditionally done so), and
that attribute objects are simply create in-place at the point of access. So to
clarify my previous code a bit:

attribute class A { string i = "Default"; }

@A class C { A a; }

void main()
{
auto a = C@A; // create new A based on C
assert(is(typeof(a) : A));

// alternatively you could do:
auto c = new C();
auto a = c@A; // same as: typeof(c)@A

c.a = c@A; // explicitly store attribute
}

Note: Might want to use the "new" keyword with class type attributes (auto a =
new C@A), but the idea's there. Plus, I think that looks a lot better than the
C# version.


Sorry, it still looks like standard lazy initialization. I don't know what 
attributes add to the party.




Sounds like a garden variety user-defined data type.


It is. Only it's a data type who's construction values are stored in metadata
(per entity), and therefor can be used at both compile and run times. By
per-entity I mean for each unique Type, Type member, Sub-Type, etc.

I don't know of any existing D idiom that is capable of what I presented.


Simply use a normal class. Instantiate it at runtime as needed.



which, aside from noise, is great for runtime reflection, but it's completely
useless (i think) for the compiler because the variables are created through
arbitrary strings. Plus, I don't know how you'd store anything but simple
variables, which more complex data would require a lot of _variables.


Something like Jacob's proposal for compile time attributes would be useful 
here. My failure to understand is about runtime attributes.


Re: Proposal: user defined attributes

2012-03-18 Thread Jacob Carlborg

On 2012-03-18 20:26, Walter Bright wrote:


Something like Jacob's proposal for compile time attributes would be
useful here. My failure to understand is about runtime attributes.


If we'll get user defined attributes that is accessible via runtime 
reflection I'm sure people will find uses cases for it that are not 
possible with compile time reflection. But currently I don't see any use 
cases for attributes per instance.


If I'm thinking correctly this can be used for serializing. Say that you 
want to serialize an object through a base class reference. Currently 
you will need to register the subclass using some mechanism due to the 
limited runtime reflection in D. But if it would be possible to 
enumerate all fields in a class and also set and get the values of the 
fields using runtime reflection it wouldn't be necessary to register the 
subclass.


Ok, now to the user defined attribute:

@attribute class NonSerialized {} // This is what's called a "marker" in 
Java. It doesn't contain any information, the information is the type 
itself.


@attribute class SerializeAs
{
string value;
}

class Base
{
int x;
@SerializeAs(foo) int y;
@NonSerialized int c;
}

@NonSerialized class Sub : Base
{
int z;
}

Base sub = new Sub;
serialize(sub);

In this example the user defined attribute "NonSerialized" indicates 
that the class shouldn't be serialized. When the serializer is 
serializing "sub" the compile time type will be "Base" therefore it 
would need to use runtime reflection to also serialize the fields added 
in the subclass "Sub". To check if the object should be serialized the 
serializer need to be able to access user defined attributes using 
runtime reflection. Something like:


auto classInfo = sub.classinfo;
writeln(classInfo); // Sub

if (classInfo.hasAttribute("NonSerialized"))
// skip serialization

else
{
foreach (field ; classInfo.fields)
if (!field.hasAttribute("NonSerialized"))
{
auto value = filed.value;
string name;

if (attribute = filed.attributes["SerializeAs"])
name = attribute.value;

else
name = filed.name;

// serialize the field
}
}

We do all this during runtime because we want to serialize through base 
class references. If the runtime type is the same as the compile time 
type we can do this at compile time.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-18 Thread Walter Bright

On 3/18/2012 2:58 PM, Jacob Carlborg wrote:

Ok, now to the user defined attribute:

@attribute class NonSerialized {} // This is what's called a "marker" in Java.
It doesn't contain any information, the information is the type itself.

@attribute class SerializeAs
{
string value;
}

class Base
{
int x;
@SerializeAs(foo) int y;
@NonSerialized int c;
}

@NonSerialized class Sub : Base
{
int z;
}

Base sub = new Sub;
serialize(sub);

In this example the user defined attribute "NonSerialized" indicates that the
class shouldn't be serialized. When the serializer is serializing "sub" the
compile time type will be "Base" therefore it would need to use runtime
reflection to also serialize the fields added in the subclass "Sub". To check if
the object should be serialized the serializer need to be able to access user
defined attributes using runtime reflection.


I'm sorry, I find this *massively* confusing. What is foo? Why are you 
serializing something marked "NonSerialized"? I really have no idea what is 
going on with this. What is the serialize() function? How does any of this tell 
you how to serialize an int? How is Base.c also a NonSerialized with c in a 
superclass of it?


??

Maybe this is why I don't much care for attributes - it's all just a fog to me 
what is happening.


Re: Proposal: user defined attributes

2012-03-18 Thread bearophile

On Friday, 16 March 2012 at 13:35:55 UTC, Adam D. Ruppe wrote:

On the ride over here today, I had a thought that
I think neatly solves the user defined attribute
question.


Maybe there are other ways to think about user defined 
attributes. I'd like them to essentially be ways to extend the 
static type system in library code.


I am thinking about things like the ones done by Dehydra and 
Treehydra (https://developer.mozilla.org/en/Dehydra  
https://developer.mozilla.org/en/Treehydra ) but using the D 
language itself instead of JavaScript.


This asks for more __traits(...), to allow the D programmer (that 
is defining a new attribute) to use them to static verify more 
characteristics of the D code being annotated with the attributes.


Bye,
bearophile


Re: Proposal: user defined attributes

2012-03-18 Thread F i L

Walter Bright wrote:
I'm sorry, I find this *massively* confusing. What is foo? Why 
are you serializing something marked "NonSerialized"? I really 
have no idea what is going on with this. What is the 
serialize() function?


He's giving an example of serialize() below the code you quoted.



Walter Bright wrote:

Which looks indistinguishable from modifiable at runtime,
instance specific data.


If you're *only* considering the runtime ability of attributes, 
then it is. This:


attribute struct A { this(int x, int y); void foo(); }
@A(1, 2) struct C {}

void main() {
auto a = C@A;
a.foo();
}

would be conceptually equivalent to writing:

struct A { this(int x, int y); void foo(); }
struct C { static auto _A() { return A(1, 2); } }

void main() {
auto a = C._A();
a.foo();
}

and it's my fault for not illustrating the important difference 
in the first place. Which is: Attributes are understandable by 
the compiler, therefor, attributes can describe behavior of an 
entity and inject code into key places where that entity is 
allocated/constructed/etc. For instance, C# does not directly 
support Unions, however creating the structure is possible, like 
so:


[StructLayout(LayoutKind.Explicit)]
struct MyUnion
{
[FieldOffset(0)] int a;
[FieldOffset(0)] long b;
[FieldOffset(0)] float c;
}


Because Attributes are defined with unique syntax, they can be 
stored uniquely by the compiler, and then reacted upon _in a 
variety of ways_. They are available at runtime so that runtime 
code can react to them as well.


To illustrate what Trove and I have been talking about, If I 
wanted to "mark" a variable so that the GC wouldn't scan it, I 
might be able to write something like:


attribute class Memory {
GC.BlkAttr blkAttr;

this(GC.BlkAttr attr) { blkAttr = attr; }

@this(void* entity) {
// the code in this function gets injected into
// this() of the entity this class is attached to

GC.setAttr(entity, blkAttr);
}
}

The "@this(void*)" function might always take in a void* (much 
like how new() always takes uint/size_t) which points to the 
entity it's attributing. So if we then write:


@Memory(GC.BlkAttr.NO_SCAN) string myString;

Then when "myString.init()" is called,
"GC.setAttr(myString, GC.BlkAttr.NO_SCAN)" will also be executed. 
I don't know enough about DMD's internals to know about how this 
would play out internally, but the concept is there.


And I know my syntax has be changing over the last few posts 
(I've been going through different ideas), so I apologize if I'm 
being hard to follow here.


Re: Proposal: user defined attributes

2012-03-18 Thread dennis luehring

Am 19.03.2012 01:41, schrieb Walter Bright:

I'm sorry, I find this *massively* confusing. What is foo? Why are you
serializing something marked "NonSerialized"? I really have no idea what is
going on with this. What is the serialize() function? How does any of this tell
you how to serialize an int? How is Base.c also a NonSerialized with c in a
superclass of it?


attributes does not containing code - there just a (at-runtime) 
queryable information that can be attached to serveral things (like 
classes, methods, ...) - think of it like double.epsilon - but 
extendable by users - thats it, and in the c# world these 
attribute-definitions tend to be something like an class (but without code)


in c# you can walk by (runtime)reflection through your code and find out 
if something is annotated with an special attribute and use the 
configure information and do something with it - call an constructor, 
open an connection, generated code (at runtime) - whatever you want


its a easy-to-use-buildin-attribution-system thats it - and people like 
them because c# do all the big magic by giving developers a bunch of 
attributes that are then used for stuff like serialization, 
memory-layout, ...


a compiletime example of this could be:

attribute my_special_attribute
{
   int version;
}

attribute my_special_attribute2
{
   string test;
}

class test
{
   [my_special_attribute(version=2)]
   int method1();

   [my_special_attribute(version=2)]
   [my_special_attribute2(test="bert")]
   int method2();
}

void main()
{
  auto b = [ __traits(allMembers, D) ];
  foreach( auto a; b )
  {
-->attribute query magic
-->auto c = [ __traits(attribute("my_special_attribute", a) ];
-->auto c = [ __traits(attribute("my_special_attribute2", a) ];

//now we know all methods with my_special_attribute
//and speical_special_attribute2 and their content (version=2
//and test="bert"

//now think of an template or mixing that uses this
//information for code-generation or something like that

//thats all
  }
}






Re: Proposal: user defined attributes

2012-03-19 Thread Paulo Pinto

Except for shared types, since in C# data is shared by default, everything
else is available:

RAII-> using ()
immutable -> achieved via cons/readonly (good enough for most purposes)
ThreadLocal -> ThreadLocal class

"Walter Bright"  wrote in message news:jk3esn$1697$1...@digitalmars.com...

On 3/17/2012 6:39 PM, Manu wrote:
I'm sure C# already answers all these questions. It has precisely the same 
set

of issues associated.


C# doesn't have RAII, immutable, nor the notion of threadlocal/shared types. 



Re: Proposal: user defined attributes

2012-03-19 Thread Tove

On Monday, 19 March 2012 at 06:46:09 UTC, dennis luehring wrote:

Am 19.03.2012 01:41, schrieb Walter Bright:
I'm sorry, I find this *massively* confusing. What is foo? Why 
are you
serializing something marked "NonSerialized"? I really have no 
idea what is
going on with this. What is the serialize() function? How does 
any of this tell
you how to serialize an int? How is Base.c also a 
NonSerialized with c in a

superclass of it?


attributes does not containing code - there just a (at-runtime) 
queryable information that can be attached to serveral things 
(like classes, methods, ...) - think of it like double.epsilon 
- but extendable by users - thats it, and in the c# world these 
attribute-definitions tend to be something like an class (but 
without code)


in c# you can walk by (runtime)reflection through your code and 
find out if something is annotated with an special attribute 
and use the configure information and do something with it - 
call an constructor, open an connection, generated code (at 
runtime) - whatever you want


its a easy-to-use-buildin-attribution-system thats it - and 
people like them because c# do all the big magic by giving 
developers a bunch of attributes that are then used for stuff 
like serialization, memory-layout, ...


a compiletime example of this could be:

attribute my_special_attribute
{
   int version;
}

attribute my_special_attribute2
{
   string test;
}

class test
{
   [my_special_attribute(version=2)]
   int method1();

   [my_special_attribute(version=2)]
   [my_special_attribute2(test="bert")]
   int method2();
}

void main()
{
  auto b = [ __traits(allMembers, D) ];
  foreach( auto a; b )
  {
-->attribute query magic
-->auto c = [ __traits(attribute("my_special_attribute", a) 
];
-->auto c = [ __traits(attribute("my_special_attribute2", 
a) ];


//now we know all methods with my_special_attribute
//and speical_special_attribute2 and their content 
(version=2

//and test="bert"

//now think of an template or mixing that uses this
//information for code-generation or something like that

//thats all
  }
}


Well I was thinking if we can go one step further than C#, 
because of D:s CTFE... by introducing a call back from the D 
compiler to the library CTFE attribute handler... this way we can 
hide all reflection from the "end user"... and the compiler 
doesn't need to know anything at all, as the library does the 
semantic lowering.


@GC.NoScan int value;
@GC this() {}

Compiler Asks library for transformation of unknown @GC
bool library("@GC this() {anything...}") ->

if the library succeeds it would then transform the string and 
hand back a lowered mixin to the compiler.


mixin("
this()
{
  auto b = [ __traits(allMembers, D) ];
  foreach( auto a; b) {DO.GC.Stuff...}

  anything...
}
");




Re: Proposal: user defined attributes

2012-03-19 Thread dennis luehring

i don't get the GC relation here?

all attribute values are static const - because they are type-related 
(static) and read-only, attributes are type orientated not instance 
orientated



@GC.NoScan int value;
@GC this() {}

Compiler Asks library for transformation of unknown @GC
bool library("@GC this() {anything...}") ->

if the library succeeds it would then transform the string and
hand back a lowered mixin to the compiler.

mixin("
this()
{
auto b = [ __traits(allMembers, D) ];
foreach( auto a; b) {DO.GC.Stuff...}

anything...
}
");








Re: Proposal: user defined attributes

2012-03-19 Thread Jacob Carlborg

On 2012-03-19 01:41, Walter Bright wrote:

On 3/18/2012 2:58 PM, Jacob Carlborg wrote:

Ok, now to the user defined attribute:

@attribute class NonSerialized {} // This is what's called a "marker"
in Java.
It doesn't contain any information, the information is the type itself.

@attribute class SerializeAs
{
string value;
}

class Base
{
int x;
@SerializeAs(foo) int y;
@NonSerialized int c;
}

@NonSerialized class Sub : Base
{
int z;
}

Base sub = new Sub;
serialize(sub);

In this example the user defined attribute "NonSerialized" indicates
that the
class shouldn't be serialized. When the serializer is serializing
"sub" the
compile time type will be "Base" therefore it would need to use runtime
reflection to also serialize the fields added in the subclass "Sub".
To check if
the object should be serialized the serializer need to be able to
access user
defined attributes using runtime reflection.


I'm sorry, I find this *massively* confusing. What is foo?


It should have been:

@SerializeAs("foo") int y;

"foo" is the name "y" will be serialized with. Just to show an example 
with an attribute accepting a value.



Why are you
serializing something marked "NonSerialized"? I really have no idea what
is going on with this. What is the serialize() function? How does any of
this tell you how to serialize an int? How is Base.c also a
NonSerialized with c in a superclass of it?


This example might not have been the best one. I might not know that 
"Sub" is marked as "NonSerialized". An instance of "Sub" can be part of 
another class that is not marked as "NonSerialized".


"serialize" would be the function that performs the serialization. I 
cannot write a whole serialization in a newsgroup message, can I :)


This example also shows that "NonSerialized" can be applied to 
individual fields of a class.


This tell how to serialize an int. It tells if a part of an object 
hierarchy (class, or field) should be serialized or not.



??

Maybe this is why I don't much care for attributes - it's all just a fog
to me what is happening.


I think it's quite clear what is happening. But I've might squeezed in 
too much in a too small example.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-19 Thread F i L

dennis luehring wrote:

i don't get the GC relation here?

all attribute values are static const - because they are 
type-related (static) and read-only, attributes are type 
orientated not instance orientated


C# doesn't support free-types (everything's wrapped up in 
classes) so the technique isn't going to be identical. In D, 
you'd need to be able to declare an attribute on virtually any 
entity declaration and have the compiler dish out the appropriate 
code.


Trove's suggesting that the compiler simply looks up user-defined 
functions associated with  and inject the code into 
the appropriate place, which I think is a good idea. The problem 
I see is how to do more advanced structural changes like C# does 
with [FieldOffset(0)]. Things like:


@Int.Fast int index;
assert(index.sizeof == int.sizeof) // always?

which might break the type system, so I'm not sure it's even 
possible. The compiler might have passed the point of no-return 
with such attributes.


Regardless, I think was Trove's suggesting would work well.


Re: Proposal: user defined attributes

2012-03-19 Thread Manu
On 19 March 2012 08:46, dennis luehring  wrote:

>
> attributes does not containing code - there just a (at-runtime) queryable
> information that can be attached to serveral things (like classes, methods,
> ...) - think of it like double.epsilon - but extendable by users - thats
> it, and in the c# world these attribute-definitions tend to be something
> like an class (but without code)
>
> in c# you can walk by (runtime)reflection through your code and find out
> if something is annotated with an special attribute and use the configure
> information and do something with it - call an constructor, open an
> connection, generated code (at runtime) - whatever you want
>
> its a easy-to-use-buildin-**attribution-system thats it - and people like
> them because c# do all the big magic by giving developers a bunch of
> attributes that are then used for stuff like serialization, memory-layout,
> ...
>
> a compiletime example of this could be:
>
> attribute my_special_attribute
> {
>   int version;
> }
>
> attribute my_special_attribute2
> {
>   string test;
> }
>
> class test
> {
>   [my_special_attribute(version=**2)]
>   int method1();
>
>   [my_special_attribute(version=**2)]
>   [my_special_attribute2(test="**bert")]
>   int method2();
> }
>
> void main()
> {
>  auto b = [ __traits(allMembers, D) ];
>  foreach( auto a; b )
>  {
>-->attribute query magic
>-->auto c = [ __traits(attribute("my_**special_attribute", a) ];
>-->auto c = [ __traits(attribute("my_**special_attribute2", a) ];
>
>//now we know all methods with my_special_attribute
>//and speical_special_attribute2 and their content (version=2
>//and test="bert"
>
>//now think of an template or mixing that uses this
>//information for code-generation or something like that
>
>//thats all
>  }
> }
>

+1 this post


Re: Proposal: user defined attributes

2012-03-19 Thread Jacob Carlborg

On 2012-03-19 09:01, Tove wrote:

Well I was thinking if we can go one step further than C#, because of
D:s CTFE... by introducing a call back from the D compiler to the
library CTFE attribute handler... this way we can hide all reflection
from the "end user"... and the compiler doesn't need to know anything at
all, as the library does the semantic lowering.

@GC.NoScan int value;
@GC this() {}

Compiler Asks library for transformation of unknown @GC
bool library("@GC this() {anything...}") ->

if the library succeeds it would then transform the string and hand back
a lowered mixin to the compiler.

mixin("
this()
{
auto b = [ __traits(allMembers, D) ];
foreach( auto a; b) {DO.GC.Stuff...}

anything...
}
");


That would be cool.

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-19 Thread dennis luehring

Am 19.03.2012 10:03, schrieb F i L:

dennis luehring wrote:

 i don't get the GC relation here?

 all attribute values are static const - because they are
 type-related (static) and read-only, attributes are type
 orientated not instance orientated


C# doesn't support free-types (everything's wrapped up in
classes) so the technique isn't going to be identical. In D,
you'd need to be able to declare an attribute on virtually any
entity declaration and have the compiler dish out the appropriate
code.

Trove's suggesting that the compiler simply looks up user-defined
functions associated with  and inject the code into
the appropriate place, which I think is a good idea. The problem
I see is how to do more advanced structural changes like C# does
with [FieldOffset(0)]. Things like:

  @Int.Fast int index;
  assert(index.sizeof == int.sizeof) // always?

which might break the type system, so I'm not sure it's even
possible. The compiler might have passed the point of no-return
with such attributes.

Regardless, I think was Trove's suggesting would work well.


sound to simple to fit in non trival cases


Re: Proposal: user defined attributes

2012-03-19 Thread Steven Schveighoffer
On Sun, 18 Mar 2012 04:03:29 -0400, Walter Bright  
 wrote:



On 3/17/2012 10:01 PM, F i L wrote:

Walter Bright wrote:
My impression is it is just obfuscation around a simple lazy  
initialization

pattern.

While I can see the abstraction usefulness of compile time attribute  
metadata,
I am having a hard time seeing what the gain is with runtime  
attributes over

more traditional techniques.


I'm not sure exactly what you mean by runtime attributes. Do you mean  
the

ability to reflect upon attributes at runtime?


I mean there is modifiable-at-runtime, instance-specific data.


I don't think we should go this far with attributes.  If you want to store  
instance-specific data, we already have a place for that.  I haven't been  
exactly groking all of this thread, but I understand what attributes are  
useful for having used them quite a bit in C#.


Again, I am just not seeing the leap in power with this. It's a mystery  
to me how a user defined "attribute class" is different in any way from  
a user defined class, and what advantage special syntax gives a standard  
pattern for lazy initialization, and why extra attribute fields can't be  
just, well, fields.


The advantage is it hooks you into the compiler's generation of metadata  
and runtime type information (i.e. TypeInfo).  It basically allows you to  
describe your type in ways that the compiler doesn't natively support.   
It's purely a type-description thing, I think it has nothing to do with  
instances.


The serializable example is probably most used because it's one of the  
most commonly used attributes in C#/Java.  Given that neither has  
templates, the impact is somewhat greater than in D, but I believe Jacob  
has quite a bit of experience with serialization of types given that he  
wrote a serializer for D, so he would be the one I'd ask as to why it's  
better.  I think another great example is data you can pass to the GC (if  
we ever get precise scanning).


In a previous life, while using C#, I created a "scripting" system that  
used objects to define what methods were run during certain test processes  
(the application managed the automated testing of servers remotely).  The  
entire script was constructed based on an xml file, and the library that  
edited/built the script had no access or knowledge of the types it was  
constructing, it used pure reflection to do everything.  The cool thing  
(in my mind at least) was, I had a script builder application which  
"opened" the executable to find all the scripting objects.  It did not  
need to be recompiled, nor did it directly link with a library having the  
script objects, because it used reflection to determine everything I  
needed.  Some specific attributes weren't available in reflection, so I  
just added some user-defined attributes, and in that way, I was able to  
affect the metadata to pass information to the script building application.


I think also you can make code more readable and easier to write with  
attributes, because you can specify/convey information rather than  
interpreting or making assumptions, or inventing types that have nothing  
to do with the way the type works.


For example, you could do something like:

struct noSerInt
{
   int _val;
   alias this _val;
}

struct X
{
   noSerInt x; // clue to not serialize x
}

This is extra complication which is not needed while using an instance of  
X *except* when serializing it.  I think it's cleaner to put this  
information into the metadata instead of having to re-implement int.   
Compare to:


struct X
{
   @noSer int x;
}

Where you can safely ignore the @noSer attribute for most intents and  
purposes.


I think that the sole purpose of attributes is compile-time generation of  
compile and run-time query-able data.  Nothing else really makes sense to  
me.


-Steve


Re: Proposal: user defined attributes

2012-03-19 Thread dennis luehring

exactly my point - thx

Am 19.03.2012 13:31, schrieb Steven Schveighoffer:

On Sun, 18 Mar 2012 04:03:29 -0400, Walter Bright
  wrote:


 On 3/17/2012 10:01 PM, F i L wrote:

 Walter Bright wrote:

 My impression is it is just obfuscation around a simple lazy
 initialization
 pattern.

 While I can see the abstraction usefulness of compile time attribute
 metadata,
 I am having a hard time seeing what the gain is with runtime
 attributes over
 more traditional techniques.


 I'm not sure exactly what you mean by runtime attributes. Do you mean
 the
 ability to reflect upon attributes at runtime?


 I mean there is modifiable-at-runtime, instance-specific data.


I don't think we should go this far with attributes.  If you want to store
instance-specific data, we already have a place for that.  I haven't been
exactly groking all of this thread, but I understand what attributes are
useful for having used them quite a bit in C#.


 Again, I am just not seeing the leap in power with this. It's a mystery
 to me how a user defined "attribute class" is different in any way from
 a user defined class, and what advantage special syntax gives a standard
 pattern for lazy initialization, and why extra attribute fields can't be
 just, well, fields.


The advantage is it hooks you into the compiler's generation of metadata
and runtime type information (i.e. TypeInfo).  It basically allows you to
describe your type in ways that the compiler doesn't natively support.
It's purely a type-description thing, I think it has nothing to do with
instances.

The serializable example is probably most used because it's one of the
most commonly used attributes in C#/Java.  Given that neither has
templates, the impact is somewhat greater than in D, but I believe Jacob
has quite a bit of experience with serialization of types given that he
wrote a serializer for D, so he would be the one I'd ask as to why it's
better.  I think another great example is data you can pass to the GC (if
we ever get precise scanning).

In a previous life, while using C#, I created a "scripting" system that
used objects to define what methods were run during certain test processes
(the application managed the automated testing of servers remotely).  The
entire script was constructed based on an xml file, and the library that
edited/built the script had no access or knowledge of the types it was
constructing, it used pure reflection to do everything.  The cool thing
(in my mind at least) was, I had a script builder application which
"opened" the executable to find all the scripting objects.  It did not
need to be recompiled, nor did it directly link with a library having the
script objects, because it used reflection to determine everything I
needed.  Some specific attributes weren't available in reflection, so I
just added some user-defined attributes, and in that way, I was able to
affect the metadata to pass information to the script building application.

I think also you can make code more readable and easier to write with
attributes, because you can specify/convey information rather than
interpreting or making assumptions, or inventing types that have nothing
to do with the way the type works.

For example, you could do something like:

struct noSerInt
{
 int _val;
 alias this _val;
}

struct X
{
 noSerInt x; // clue to not serialize x
}

This is extra complication which is not needed while using an instance of
X *except* when serializing it.  I think it's cleaner to put this
information into the metadata instead of having to re-implement int.
Compare to:

struct X
{
 @noSer int x;
}

Where you can safely ignore the @noSer attribute for most intents and
purposes.

I think that the sole purpose of attributes is compile-time generation of
compile and run-time query-able data.  Nothing else really makes sense to
me.

-Steve





Re: Proposal: user defined attributes

2012-03-19 Thread RivenTheMage

On Monday, 19 March 2012 at 00:41:44 UTC, Walter Bright wrote:

Maybe this is why I don't much care for attributes - it's all 
just a fog to me what is happening.


Maybe this will help:

http://research.microsoft.com/en-us/um/people/cszypers/events/WCOP2006/rouvoy-wcop-06.pdf

Attribute-Oriented Programming (@OP) is a program-level marking
technique. Basically, this approach allows developers to mark
program elements (e.g., classes, methods, and fields) with
annotations to indicate that they maintain application specific
or domain-specific concerns. For example, a developer may define
a logging annotation and associate it with a method to indicate
that the calls to this method should be logged, or may define a
web service annotation and associate it with a class to indicate
that the class should implement a Web Service. Annotations
separate application’s business logic from middleware-specific
or domain-specific concerns (e.g., logging and web service
functions). By hiding the implementation details of those
semantics from program code, annotations increase the level of
programming abstraction and reduce programming complexity,
resulting in simpler and more readable programs. The program
elements associated with annotations are transformed to more
detailed program code by a supporting generation engine. For
example, a generation
engine may insert logging code into the methods associated with a
logging annotation. Dependencies on the underlying middleware are
thus replaced by annotations, acting as weak references — i.e.,
references that are not mandatory for the application. This means
that the evolution of the underlying middleware is taken into
account by the generation engine and let the program code
unchanged.


Re: Proposal: user defined attributes

2012-03-19 Thread Jacob Carlborg

On 2012-03-19 13:31, Steven Schveighoffer wrote:

On Sun, 18 Mar 2012 04:03:29 -0400, Walter Bright

I mean there is modifiable-at-runtime, instance-specific data.


I don't think we should go this far with attributes. If you want to
store instance-specific data, we already have a place for that. I
haven't been exactly groking all of this thread, but I understand what
attributes are useful for having used them quite a bit in C#.


I agree.


Again, I am just not seeing the leap in power with this. It's a
mystery to me how a user defined "attribute class" is different in any
way from a user defined class, and what advantage special syntax gives
a standard pattern for lazy initialization, and why extra attribute
fields can't be just, well, fields.


The advantage is it hooks you into the compiler's generation of metadata
and runtime type information (i.e. TypeInfo). It basically allows you to
describe your type in ways that the compiler doesn't natively support.
It's purely a type-description thing, I think it has nothing to do with
instances.

The serializable example is probably most used because it's one of the
most commonly used attributes in C#/Java. Given that neither has
templates, the impact is somewhat greater than in D, but I believe Jacob
has quite a bit of experience with serialization of types given that he
wrote a serializer for D, so he would be the one I'd ask as to why it's
better. I think another great example is data you can pass to the GC (if
we ever get precise scanning).


For the serialization example I think it's mostly a syntactic 
enhancement. It would also be an enhancement when accessing the attributes.


class Foo {
int a;
@NonSerialized int b;
}

class Bar
{
int a;
int b;
mixin NonSerialized!(b);
}

The advantage the attribute has is:

* Better syntax, more readable
* Shows up in the documentation of "b".
* Can be repeated on several fields (with the mixin you can only mixin 
"NonSerialized" once)

* Easier to access the attribute
* No information is added to the type itself. It would be added to the 
metadata of the type, i.e. TypeInfo


But I see many other cases where attributes would work better than mixins.


In a previous life, while using C#, I created a "scripting" system that
used objects to define what methods were run during certain test
processes (the application managed the automated testing of servers
remotely). The entire script was constructed based on an xml file, and
the library that edited/built the script had no access or knowledge of
the types it was constructing, it used pure reflection to do everything.
The cool thing (in my mind at least) was, I had a script builder
application which "opened" the executable to find all the scripting
objects. It did not need to be recompiled, nor did it directly link with
a library having the script objects, because it used reflection to
determine everything I needed. Some specific attributes weren't
available in reflection, so I just added some user-defined attributes,
and in that way, I was able to affect the metadata to pass information
to the script building application.

I think also you can make code more readable and easier to write with
attributes, because you can specify/convey information rather than
interpreting or making assumptions, or inventing types that have nothing
to do with the way the type works.

For example, you could do something like:

struct noSerInt
{
int _val;
alias this _val;
}

struct X
{
noSerInt x; // clue to not serialize x
}

This is extra complication which is not needed while using an instance
of X *except* when serializing it. I think it's cleaner to put this
information into the metadata instead of having to re-implement int.
Compare to:

struct X
{
@noSer int x;
}

Where you can safely ignore the @noSer attribute for most intents and
purposes.

I think that the sole purpose of attributes is compile-time generation
of compile and run-time query-able data. Nothing else really makes sense
to me.

-Steve


Very well explained.

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-19 Thread Andrej Mitrovic
On 3/19/12, Jacob Carlborg  wrote:
> * Can be repeated on several fields (with the mixin you can only mixin
> "NonSerialized" once)

When I implemented NonSerialized for Vladimir's json library he made a
suggestion to simply create enums of each field that is not to be
serialized and encode it as "fieldname_nonSerialized". That would
enable using a NonSerialized mixin multiple times.

I've yet to implement it in that way, I ran into some odd bugs but
I'll have a look at this soon. My implementation used a hash lookup
table for the fields, but using enums would make the code even
simpler. Basically:

struct Foo
{
int x;
string name;
mixin(NonSerialized!name);
string lastName;
mixin(NonSerialized!lastName);
}

and this would expand to:
struct Foo
{
int x;
string name;
enum name_nonSerialized;
string lastName;
enum lastName_nonSerialized;
}

So all you'd have to do is use compile-time introspection and a little
bit of string processing to figure out if a field should be serialized
or not.


Re: Proposal: user defined attributes

2012-03-19 Thread F i L

On Monday, 19 March 2012 at 20:44:43 UTC, Andrej Mitrovic wrote:

On 3/19/12, Jacob Carlborg  wrote:
* Can be repeated on several fields (with the mixin you can 
only mixin

"NonSerialized" once)


When I implemented NonSerialized for Vladimir's json library he 
made a
suggestion to simply create enums of each field that is not to 
be
serialized and encode it as "fieldname_nonSerialized". That 
would

enable using a NonSerialized mixin multiple times.

I've yet to implement it in that way, I ran into some odd bugs 
but
I'll have a look at this soon. My implementation used a hash 
lookup

table for the fields, but using enums would make the code even
simpler. Basically:

struct Foo
{
int x;
string name;
mixin(NonSerialized!name);
string lastName;
mixin(NonSerialized!lastName);
}

and this would expand to:
struct Foo
{
int x;
string name;
enum name_nonSerialized;
string lastName;
enum lastName_nonSerialized;
}

So all you'd have to do is use compile-time introspection and a 
little
bit of string processing to figure out if a field should be 
serialized

or not.



I think this could get tricky for the compiler to confidently use 
given that the mixed in enums can collide with existing members 
(although not likely). Also, if objects are not identified as 
being unique marked (in the compilers eyes), what specific 
attribute post-fixes will it be searching for on enums members?


Re: Proposal: user defined attributes

2012-03-19 Thread Andrej Mitrovic
On 3/19/12, F i L  wrote:
> Also, if objects are not identified as
> being unique marked (in the compilers eyes), what specific
> attribute post-fixes will it be searching for on enums members?

I'm really not talking about general-purpose attributes, I was
commenting on a specific serialization example. :) Also I've no idea
what "objects being unique marked" means.


Re: Proposal: user defined attributes

2012-03-19 Thread Andrei Alexandrescu

On 3/19/12 3:44 PM, Andrej Mitrovic wrote:

On 3/19/12, Jacob Carlborg  wrote:

* Can be repeated on several fields (with the mixin you can only mixin
"NonSerialized" once)


When I implemented NonSerialized for Vladimir's json library he made a
suggestion to simply create enums of each field that is not to be
serialized and encode it as "fieldname_nonSerialized". That would
enable using a NonSerialized mixin multiple times.

I've yet to implement it in that way, I ran into some odd bugs but
I'll have a look at this soon. My implementation used a hash lookup
table for the fields, but using enums would make the code even
simpler. Basically:

struct Foo
{
 int x;
 string name;
 mixin(NonSerialized!name);
 string lastName;
 mixin(NonSerialized!lastName);
}

and this would expand to:
struct Foo
{
 int x;
 string name;
 enum name_nonSerialized;
 string lastName;
 enum lastName_nonSerialized;
}

So all you'd have to do is use compile-time introspection and a little
bit of string processing to figure out if a field should be serialized
or not.


I salute creative uses of the language over defining new features.

Andrei


Re: Proposal: user defined attributes

2012-03-19 Thread Andrei Alexandrescu

On 3/19/12 3:55 PM, F i L wrote:

I think this could get tricky for the compiler to confidently use given
that the mixed in enums can collide with existing members (although not
likely). Also, if objects are not identified as being unique marked (in
the compilers eyes), what specific attribute post-fixes will it be
searching for on enums members?


Not a big issue, the name could always contain a uuid which makes 
collision practically impossibile.


Andrei


Re: Proposal: user defined attributes

2012-03-19 Thread F i L
On Monday, 19 March 2012 at 21:00:32 UTC, Andrei Alexandrescu 
wrote:

On 3/19/12 3:55 PM, F i L wrote:
I think this could get tricky for the compiler to confidently 
use given
that the mixed in enums can collide with existing members 
(although not
likely). Also, if objects are not identified as being unique 
marked (in
the compilers eyes), what specific attribute post-fixes will 
it be

searching for on enums members?


Not a big issue, the name could always contain a uuid which 
makes collision practically impossibile.


Andrei


So the compiler would always search for enums with a specific 
"--Mxxx-Nxxx-" signature? Guess that 
could work.


Re: Proposal: user defined attributes

2012-03-19 Thread H. S. Teoh
On Mon, Mar 19, 2012 at 04:00:00PM -0500, Andrei Alexandrescu wrote:
> On 3/19/12 3:44 PM, Andrej Mitrovic wrote:
[...]
> >So all you'd have to do is use compile-time introspection and a
> >little bit of string processing to figure out if a field should be
> >serialized or not.
> 
> I salute creative uses of the language over defining new features.

+1.


T

-- 
Life is too short to run proprietary software. -- Bdale Garbee


Re: Proposal: user defined attributes

2012-03-19 Thread F i L

Andrej Mitrovic wrote:

Also I've no idea what "objects being unique marked" means.


I meant that Attribute metadata is distinct data in the compilers 
eyes, ie, no name magic, just attribute lookup.


Re: Proposal: user defined attributes

2012-03-19 Thread Jacob Carlborg

On 2012-03-19 21:44, Andrej Mitrovic wrote:


When I implemented NonSerialized for Vladimir's json library he made a
suggestion to simply create enums of each field that is not to be
serialized and encode it as "fieldname_nonSerialized". That would
enable using a NonSerialized mixin multiple times.

I've yet to implement it in that way, I ran into some odd bugs but
I'll have a look at this soon. My implementation used a hash lookup
table for the fields, but using enums would make the code even
simpler. Basically:

struct Foo
{
 int x;
 string name;
 mixin(NonSerialized!name);
 string lastName;
 mixin(NonSerialized!lastName);
}

and this would expand to:
struct Foo
{
 int x;
 string name;
 enum name_nonSerialized;
 string lastName;
 enum lastName_nonSerialized;
}

So all you'd have to do is use compile-time introspection and a little
bit of string processing to figure out if a field should be serialized
or not.


Yeah, but that will complicate the retrieval of the information.

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-19 Thread Jacob Carlborg

On 2012-03-19 22:00, Andrei Alexandrescu wrote:


I salute creative uses of the language over defining new features.

Andrei


Sure, just as well as you can do object oriented programming in C, but 
it is a mess. So is this.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-19 Thread Andrej Mitrovic
On 3/19/12, Jacob Carlborg  wrote:
> Yeah, but that will complicate the retrieval of the information.

What is so complicated about extracting fields? Just iterate via .tupleof:

module test;

import std.stdio;
import std.conv;

struct Foo
{
int x;
string name;
mixin NonSerialized!name;
string lastName;
mixin NonSerialized!lastName;
string extra;
}

mixin template NonSerialized(alias field)
{
mixin("enum __attribute_nonSerialized_" ~ field.mangleof ~ ";");
}

string serialize(T)(T input)
{
string result;

foreach (i, field; input.tupleof)
{
static if (skipSerialize!(T, input.tupleof[i].mangleof))
result ~= to!string(typeof(field).init) ~ "\n";
else
result ~= to!string(field) ~ "\n";
}

return result;
}

template skipSerialize(T, string mangle)
{
enum bool skipSerialize = __traits(hasMember, T,
"__attribute_nonSerialized_" ~ mangle);
}

void main()
{
Foo foo = Foo(10, "Foo", "Bar", "Doo");
string bin = serialize(foo);
writeln(bin);
}

And by using .init instead of just skipping serialization altogether
you can unserialize at a later point even if you end up removing some
of the mixins, so you can have some binary-compatibility there.


Re: Proposal: user defined attributes

2012-03-19 Thread Kapps
On Monday, 19 March 2012 at 21:00:32 UTC, Andrei Alexandrescu 
wrote:

On 3/19/12 3:55 PM, F i L wrote:
I think this could get tricky for the compiler to confidently 
use given
that the mixed in enums can collide with existing members 
(although not
likely). Also, if objects are not identified as being unique 
marked (in
the compilers eyes), what specific attribute post-fixes will 
it be

searching for on enums members?


Not a big issue, the name could always contain a uuid which 
makes collision practically impossibile.


Andrei


And with parameters? Or how about run-time reflection, which is 
something that should be added eventually for attributes as well 
(that is, typeid(Blah).getCustomAttributes())? We can't manually 
add things into the TypeInfo. This is an already ridiculously 
hackish approach, and it *does not* work for anything besides 
trivial applications. It is completly unreasonable to expect 
everything to be done in a library; the compiler exists for a 
reason and at some point you have to draw the line. Why even 
bother having an auto keyword? Instead of 'auto a = b + c' you 
could simply use 'Auto!(b + c) a = b + c'. It is a more extreme 
example for now, but won't be too much different once more 
complicated things arise; after all, auto!2 a = 2 is not much 
different from auto a = 2. Just like it's not too much different 
for parameterless attributes (even if it is uglier and much more 
hackish), but once you get into parameters and runtime stuff it 
becomes just as ugly as the above example.


Re: Proposal: user defined attributes

2012-03-19 Thread dennis luehring
and how to add attribute parameters like DoSerialize(type=packed) for 
example - very very common in C# attributes and java annotations


http://en.wikipedia.org/wiki/Java_annotation

Am 19.03.2012 22:00, schrieb Andrei Alexandrescu:

On 3/19/12 3:44 PM, Andrej Mitrovic wrote:

 On 3/19/12, Jacob Carlborg   wrote:

 * Can be repeated on several fields (with the mixin you can only mixin
 "NonSerialized" once)


 When I implemented NonSerialized for Vladimir's json library he made a
 suggestion to simply create enums of each field that is not to be
 serialized and encode it as "fieldname_nonSerialized". That would
 enable using a NonSerialized mixin multiple times.

 I've yet to implement it in that way, I ran into some odd bugs but
 I'll have a look at this soon. My implementation used a hash lookup
 table for the fields, but using enums would make the code even
 simpler. Basically:

 struct Foo
 {
  int x;
  string name;
  mixin(NonSerialized!name);
  string lastName;
  mixin(NonSerialized!lastName);
 }

 and this would expand to:
 struct Foo
 {
  int x;
  string name;
  enum name_nonSerialized;
  string lastName;
  enum lastName_nonSerialized;
 }

 So all you'd have to do is use compile-time introspection and a little
 bit of string processing to figure out if a field should be serialized
 or not.


I salute creative uses of the language over defining new features.

Andrei




Re: Proposal: user defined attributes

2012-03-20 Thread Jacob Carlborg

On 2012-03-19 22:51, Andrej Mitrovic wrote:

On 3/19/12, Jacob Carlborg  wrote:

Yeah, but that will complicate the retrieval of the information.


What is so complicated about extracting fields? Just iterate via .tupleof:


It wasn't actually that much more complicated. But now there is one 
extra enum for each NonSerialized field.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-20 Thread Jacob Carlborg

On 2012-03-19 22:00, Andrei Alexandrescu wrote:


I salute creative uses of the language over defining new features.

Andrei


The actual point of user defined attributes it to be able to create 
domain specific attributes so we don't have to add new features to the 
language. This is also to have a sane syntax for the attributes.


I think in several cases D could have chose to implement a more general 
feature but instead implemented a very specific feature or hack.


Example:

If D supported passing delegates to a function after the function call 
several language features could have been implemented in the library 
instead.


void synchronized (void delegate () dg)
{
try
{
lock();
dg();
}
finally
unlock();
}

synchronized {
// do something
}

In the same way foreach can be implemented in a library function:

void foreach (T) (T[] arr, void delegate (T) dg)
{
for (size_t i = 0; i < arr.length; i++)
dg(arr[i]);
}

auto arr = [3, 4, 5];

foreach (arr ; e // this is the parameter to the delegate) {
writeln(e);
}

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-20 Thread F i L

Jacob Carlborg wrote:
If D supported passing delegates to a function after the 
function call several language features could have been 
implemented in the library instead.


void synchronized (void delegate () dg)
{
try
{
lock();
dg();
}
finally
unlock();
}

synchronized {
// do something
}

In the same way foreach can be implemented in a library 
function:


void foreach (T) (T[] arr, void delegate (T) dg)
{
for (size_t i = 0; i < arr.length; i++)
dg(arr[i]);
}

auto arr = [3, 4, 5];

foreach (arr ; e // this is the parameter to the delegate) {
writeln(e);
}


That's pretty slick. D would need delegate inlining + 
@forceInline before foreach could be expressed this way though.




Re: Proposal: user defined attributes

2012-03-20 Thread Jacob Carlborg

On 2012-03-20 10:49, F i L wrote:


That's pretty slick. D would need delegate inlining + @forceInline
before foreach could be expressed this way though.


Yes, but currently, as far as I know, the delegate passed to opApply is 
not inlined.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 12:50 AM, Kapps wrote:

On Monday, 19 March 2012 at 21:00:32 UTC, Andrei Alexandrescu wrote:

On 3/19/12 3:55 PM, F i L wrote:

I think this could get tricky for the compiler to confidently use given
that the mixed in enums can collide with existing members (although not
likely). Also, if objects are not identified as being unique marked (in
the compilers eyes), what specific attribute post-fixes will it be
searching for on enums members?


Not a big issue, the name could always contain a uuid which makes
collision practically impossibile.

Andrei


And with parameters? Or how about run-time reflection, which is
something that should be added eventually for attributes as well (that
is, typeid(Blah).getCustomAttributes())? We can't manually add things
into the TypeInfo.


Perhaps we should add a field of type Variant[string].


This is an already ridiculously hackish approach, and
it *does not* work for anything besides trivial applications. It is
completly unreasonable to expect everything to be done in a library; the
compiler exists for a reason and at some point you have to draw the
line.


I'm afraid I disagree. A targeted language feature definitely makes a 
library approach inferior, by definition. But adding features is 
cheating, like printing money is for a government: very tempting, with 
apparently good short-term benefits, but with devastating cumulative 
effects.


Also, as I mentioned, the availability of the easy escape hatch of 
adding a language feature thwarts creativity. Nobody will care to think 
about and come with idioms that use the language to do great things, if 
they know a language feature could be always added that makes things 
"nicer".


I'm not saying this particular feature should or should not be in the 
language, but I wish our community exercised considerably more restraint 
when it comes about adding new language features.



Why even bother having an auto keyword? Instead of 'auto a = b +
c' you could simply use 'Auto!(b + c) a = b + c'. It is a more extreme
example for now, but won't be too much different once more complicated
things arise; after all, auto!2 a = 2 is not much different from auto a
= 2. Just like it's not too much different for parameterless attributes
(even if it is uglier and much more hackish), but once you get into
parameters and runtime stuff it becomes just as ugly as the above example.


I don't think your example with auto is relevant.


Andrei


Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 1:22 AM, dennis luehring wrote:

and how to add attribute parameters like DoSerialize(type=packed) for
example - very very common in C# attributes and java annotations

http://en.wikipedia.org/wiki/Java_annotation


One more argument to the template?

Andrei



Re: Proposal: user defined attributes

2012-03-20 Thread Jacob Carlborg

On 2012-03-20 16:17, Andrei Alexandrescu wrote:

On 3/20/12 12:50 AM, Kapps wrote:



Perhaps we should add a field of type Variant[string].


No, not Variant[string] again.


This is an already ridiculously hackish approach, and
it *does not* work for anything besides trivial applications. It is
completly unreasonable to expect everything to be done in a library; the
compiler exists for a reason and at some point you have to draw the
line.


I'm afraid I disagree. A targeted language feature definitely makes a
library approach inferior, by definition. But adding features is
cheating, like printing money is for a government: very tempting, with
apparently good short-term benefits, but with devastating cumulative
effects.

Also, as I mentioned, the availability of the easy escape hatch of
adding a language feature thwarts creativity. Nobody will care to think
about and come with idioms that use the language to do great things, if
they know a language feature could be always added that makes things
"nicer".

I'm not saying this particular feature should or should not be in the
language, but I wish our community exercised considerably more restraint
when it comes about adding new language features.


See my reply to one of your other posts:

http://forum.dlang.org/thread/bccwycoexxykfgxve...@forum.dlang.org?page=9#post-jk9gk8:242t7k:241:40digitalmars.com

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-20 Thread F i L

Andrei Alexandrescu wrote:
like printing money is for a government: very tempting, with 
apparently good short-term benefits, but with devastating 
cumulative effects.


RON PAUL 2012!!!

sorry, I couldn't help myself.


Also, as I mentioned, the availability of the easy escape hatch 
of adding a language feature thwarts creativity. Nobody will 
care to think about and come with idioms that use the language 
to do great things, if they know a language feature could be 
always added that makes things "nicer".


You can be creative with a sledge hammer, or you can be creative 
with a jack hammer. D is already a bulldozer, but that doesn't 
mean it shouldn't become a wreaking ball.


;-)




Re: Proposal: user defined attributes

2012-03-20 Thread Steven Schveighoffer
On Tue, 20 Mar 2012 11:17:02 -0400, Andrei Alexandrescu  
 wrote:



Perhaps we should add a field of type Variant[string].


1. Variant is not (and shouldn't be IMO) part of druntime.
2. This is *static* data that should be available at compile time.  D's  
runtime wasting cycles filling in static data (including lots of heap  
allocations) seems like a big enough detriment that compiler help is  
warranted.



This is an already ridiculously hackish approach, and
it *does not* work for anything besides trivial applications. It is
completly unreasonable to expect everything to be done in a library; the
compiler exists for a reason and at some point you have to draw the
line.


I'm afraid I disagree. A targeted language feature definitely makes a  
library approach inferior, by definition. But adding features is  
cheating, like printing money is for a government: very tempting, with  
apparently good short-term benefits, but with devastating cumulative  
effects.


Not exactly.  We could all be writing code in assembly if "adding  
features" was always caustic.


What is nice about adding this feature is it provides a custom solution to  
hooking the compiler's TypeInfo generation.  We are setting up the  
compiler to give us hooks so we *don't* have to extend the compiler every  
time we want new reflection features.


One of the oft-requested features of D is reflection capability.  The  
answer is generally that we have compile-time reflection, which can  
theoretically be used to build runtime reflection.  However, the rebuttal  
I always come back with is "yeah, but why should I build at runtime that  
which is obvious at compile time?"


Note that one library that did attempt runtime reflection capability  
(flectioned) does all this at runtime, and does some really funky shit,  
like opening /proc/self/map on Linux, or requiring you to pass an OPTLINK  
map file.  I don't look at these as "innovations" as much as I do as  
workarounds.


Also, as I mentioned, the availability of the easy escape hatch of  
adding a language feature thwarts creativity. Nobody will care to think  
about and come with idioms that use the language to do great things, if  
they know a language feature could be always added that makes things  
"nicer".


I have to disagree for this instance, the barrier to creating reflection  
data from compile-time info is very large.  If anything, this *expands*  
the ability to create, since you now have a new way to pass information  
from compiler to runtime.


-Steve


Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 10:52 AM, Jacob Carlborg wrote:

On 2012-03-20 16:17, Andrei Alexandrescu wrote:

On 3/20/12 12:50 AM, Kapps wrote:



Perhaps we should add a field of type Variant[string].


No, not Variant[string] again.


Why? I thought it was agreed that that's a good idea for exceptions.


I'm not saying this particular feature should or should not be in the
language, but I wish our community exercised considerably more restraint
when it comes about adding new language features.


See my reply to one of your other posts:

http://forum.dlang.org/thread/bccwycoexxykfgxve...@forum.dlang.org?page=9#post-jk9gk8:242t7k:241:40digitalmars.com


I understand the intention there, but my point stands: let's first 
explore doing it in the language, and advocate a new feature only when 
that fails. We've been too trigger-happy about proposing features even 
for the most trivial inconveniences.



Andrei




Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 11:09 AM, Steven Schveighoffer wrote:

On Tue, 20 Mar 2012 11:17:02 -0400, Andrei Alexandrescu
 wrote:


Perhaps we should add a field of type Variant[string].


1. Variant is not (and shouldn't be IMO) part of druntime.
2. This is *static* data that should be available at compile time. D's
runtime wasting cycles filling in static data (including lots of heap
allocations) seems like a big enough detriment that compiler help is
warranted.


Forgot to mention - I snipped these points because I agree with them.

Andrei



Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 11:09 AM, Steven Schveighoffer wrote:

On Tue, 20 Mar 2012 11:17:02 -0400, Andrei Alexandrescu
 wrote:

I'm afraid I disagree. A targeted language feature definitely makes a
library approach inferior, by definition. But adding features is
cheating, like printing money is for a government: very tempting, with
apparently good short-term benefits, but with devastating cumulative
effects.


Not exactly. We could all be writing code in assembly if "adding
features" was always caustic.


This is trivializing my point. Please.


What is nice about adding this feature is it provides a custom solution
to hooking the compiler's TypeInfo generation. We are setting up the
compiler to give us hooks so we *don't* have to extend the compiler
every time we want new reflection features.


There is something nice about every new feature.


One of the oft-requested features of D is reflection capability. The
answer is generally that we have compile-time reflection, which can
theoretically be used to build runtime reflection. However, the rebuttal
I always come back with is "yeah, but why should I build at runtime that
which is obvious at compile time?"


I thought there were discussions that didn't add runtime overhead.


Note that one library that did attempt runtime reflection capability
(flectioned) does all this at runtime, and does some really funky shit,
like opening /proc/self/map on Linux, or requiring you to pass an
OPTLINK map file. I don't look at these as "innovations" as much as I do
as workarounds.


Maybe there's a better approach than flectioned. Consider the language 
is frozen solid. How would you solve problems with it?



Also, as I mentioned, the availability of the easy escape hatch of
adding a language feature thwarts creativity. Nobody will care to
think about and come with idioms that use the language to do great
things, if they know a language feature could be always added that
makes things "nicer".


I have to disagree for this instance, the barrier to creating reflection
data from compile-time info is very large. If anything, this *expands*
the ability to create, since you now have a new way to pass information
from compiler to runtime.


I hope I'll be convinced.


Andrei


Re: Proposal: user defined attributes

2012-03-20 Thread Adam D. Ruppe
On Tuesday, 20 March 2012 at 15:17:04 UTC, Andrei Alexandrescu 
wrote:
Also, as I mentioned, the availability of the easy escape hatch 
of adding a language feature thwarts creativity.


I agree entirely. Usually, when I see threads like this,
my response is "challenge accepted".

But, on this problem, my answer is, unfortunately,
"challenge failed".

I want to annotate declarations for my web.d, where
you can write a class and have D do a bunch of work
for you in creating all kinds of stuff.

Let me do up a quick example:

===
struct MyType {
   int num;
   string name;
   string desc;
   Element makeHtmlElement() {
  auto e = Element.make("div", desc).addClass("my-type");
  return e;
   }
}

class MySite : ApiProvider {
MyType getSomething(int someNumber, string name, Text 
description) {

 return MyType(someNumber, name, description);
}

void savePhoneNumber(string name, string phoneNumber) {
_checkLoggedIn();
ensureGoodPost();
_doSave();
}

void _doSave() { yada yada yada }
}
===


Now, when you go to mysite.com/get-something, it will
generate a form like this:

  
  Some Number: 
 Name: 
  Description: 
   
   

  [Get Something]
   



It pulls this info from the D code - it uses an alias
template param to the method, then parses .stringof
to get the names and default params. (It then mixes
in the default to get a D type, which doesn't work
on custom types since they aren't in the right scope,
but hey, it works in a lot of cases.)



When possible, it uses the type of the parameter
to specialize the form. This comes from ParameterTypeTuple.

Here, it recognizes struct Text{} as being a textarea.
tbh, I'd prefer to use @note(Textarea(rows)), but this
works, and alias this to string makes it pretty natural
to work with too.



Moreover, I wrote method="GET". It pulls this from the
method name. Since it starts with get, it doesn't require
http post for it.



So far, so good. Let's look at the next method, savePhoneNumber.
This !startsWith("get"), so it generates a POST form, with
the same kind of thing:

Name: _
Phone Number: _
 [Save Phone Number]


Hey, it works. But, I'd like to do even better. Could
we do validation?

Well, yeah, I think we could.

struct PhoneNumber {
 enum _validationRegex = "[0-9]+";
}

Boom.

What about an example text, though? You could use
that same enum method, but you would need a different
type for each example.

If you have two "string name" and in one case, you want
it to be "e.g. Bob Smith" and in the other, you want
"e.g. Downtown Office", you'd have to make separate
structs for them, despite it just being strings in
every other way.


That's one big case where the compile time annotation
comes through:

void savePhoneNumber
@note(ExampleText("e.g. Downtown Office")
string name,
PhoneNumber phoneNumber)
{ }


To do that with a mixin, you might:

mixin(ExampleText!(savePhoneNumber, "name", "downtown"));
void savePhoneNumber(string name, ...) {...}

and have that yield:

enum _attribute_DsavePhoneNumberMangle_param_name_FILE_LINE_type 
= ExampleText("downtown");




ok, this is a bit of a pain in the ass, but I think it'd
work... (the file_line_type stuff is so you can have multiple
things of the same type. Moderately fragile! But, it'd work.)


The pain gets bad down the line though. Renaming things means
repetition. Separate declarations might get lost as you
shuffle the order around. But, not too awful...


Until you get into more functions. Enter 
arsd.web.prepareReflection

and makeJavascriptApi:

foreach(member; __traits(allMembers, yourclass))
// build a runtime map and corresponding bindings for other 
languages




Should our enum be included here? Should this include code
to detect the annotations and translate them to the
native target language? How much code is this going to take?

What if I use a third party lib? Will it have to be hacked to
ignore these extra names too?


Well, we can work around this too. web.d has a convention
where static if(name[0] == '_') { don't process }. (This
is actually a workaround for a lack of __traits(getProtection)
though. We already have D keywords that do this: public
and/or export. But, there's currently no way to check for these,
so I settled for a naming convention.

This is what _doSave() demonstrates in the example.

I'm hoping to do a dmd pull request to add getProtection at
some point though.)

We could all agree on a naming convention, in theory. In
practice, I don't know. If I could check export || public,
I might drop the underscore.



Another problem is how do we get this data? We have
an alias of the method... but not it's parent. Well,
there's __traits(getParent). I think we could actually
do that.

But the idea of a parent reminds me of another problem.
This is a class, the method is virtu

Re: Proposal: user defined attributes

2012-03-20 Thread sclytrack

On 03/20/2012 05:31 PM, Adam D. Ruppe wrote:


Even /ignoring/ them takes a lot code, and that's
what, to me, pushes it over into compiler territory.


vote++


Re: Proposal: user defined attributes

2012-03-20 Thread Piotr Szturmaj

Andrei Alexandrescu wrote:

On 3/20/12 10:52 AM, Jacob Carlborg wrote:

On 2012-03-20 16:17, Andrei Alexandrescu wrote:

On 3/20/12 12:50 AM, Kapps wrote:



Perhaps we should add a field of type Variant[string].


No, not Variant[string] again.


Why? I thought it was agreed that that's a good idea for exceptions.


Please, do not transform D into a dynamic language.


Re: Proposal: user defined attributes

2012-03-20 Thread Andrei Alexandrescu

On 3/20/12 2:04 PM, Piotr Szturmaj wrote:

Andrei Alexandrescu wrote:

On 3/20/12 10:52 AM, Jacob Carlborg wrote:

On 2012-03-20 16:17, Andrei Alexandrescu wrote:

On 3/20/12 12:50 AM, Kapps wrote:



Perhaps we should add a field of type Variant[string].


No, not Variant[string] again.


Why? I thought it was agreed that that's a good idea for exceptions.


Please, do not transform D into a dynamic language.


Where's the "dynamic languages rok" crowd when you need it :o).

Andrei


Re: Proposal: user defined attributes

2012-03-20 Thread deadalnix

Le 20/03/2012 16:17, Andrei Alexandrescu a écrit :

On 3/20/12 12:50 AM, Kapps wrote:

On Monday, 19 March 2012 at 21:00:32 UTC, Andrei Alexandrescu wrote:

On 3/19/12 3:55 PM, F i L wrote:

I think this could get tricky for the compiler to confidently use given
that the mixed in enums can collide with existing members (although not
likely). Also, if objects are not identified as being unique marked (in
the compilers eyes), what specific attribute post-fixes will it be
searching for on enums members?


Not a big issue, the name could always contain a uuid which makes
collision practically impossibile.

Andrei


And with parameters? Or how about run-time reflection, which is
something that should be added eventually for attributes as well (that
is, typeid(Blah).getCustomAttributes())? We can't manually add things
into the TypeInfo.


Perhaps we should add a field of type Variant[string].


This is an already ridiculously hackish approach, and
it *does not* work for anything besides trivial applications. It is
completly unreasonable to expect everything to be done in a library; the
compiler exists for a reason and at some point you have to draw the
line.


I'm afraid I disagree. A targeted language feature definitely makes a
library approach inferior, by definition. But adding features is
cheating, like printing money is for a government: very tempting, with
apparently good short-term benefits, but with devastating cumulative
effects.

Also, as I mentioned, the availability of the easy escape hatch of
adding a language feature thwarts creativity. Nobody will care to think
about and come with idioms that use the language to do great things, if
they know a language feature could be always added that makes things
"nicer".

I'm not saying this particular feature should or should not be in the
language, but I wish our community exercised considerably more restraint
when it comes about adding new language features.



That feature has been added to java with great benefit. I think the 
underlying need here is AOP. Adding annotation to java had great 
benefice in introducing AOP capabilities to the language.


See :
http://projectlombok.org/

Considering that D has great compile time capabilities, this is 
somewhere we want to go.


Additionnaly, this is something that remove other capabilities, and 
replace them by lib support. For example, with @synchronized, I could 
specify the phobos that I want that method or class to be synchronized, 
and the lib is able to add the needed code to ensure that functionality 
at compile time.


I have to say that the whole idea of attaching property to instance 
doesn't make any sense to me - Walter make a good point on that I think, 
so I will not repeat his arguments.


  1   2   >