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.

Reply via email to