Proposal: user defined attributes
F i L
witte2008 at gmail.com
Sun Mar 18 22:33:07 PDT 2012
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 at 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.
More information about the Digitalmars-d
mailing list