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