I don't want this thread to disappear. The ideas presented here have common 
basic features among the nice-to-haves.

1. Attributes add meta data baggage to a symbol
2. This meta data is thought of as a read-only hash (has, get, iterate)
3. Can be queried at compile-time
4. The syntax is concise (i.e. improves over implementing attributes 'manually' 
with mixins)

Now the compiler has solved things (what is a symbol, an AST, ...) in one 
specific way and to keep it stable and the amount of work within bounds, any 
implementation details of attributes that make invasive changes necessary 
should be postponed. I don't know the compiler, so it is just my gut feeling 
when I say that annotating local variables could be a refinement to 1) that 
doesn't work well. You get the point.

With that in mind it would be good to know exactly what can simply be tacked 
onto the front-end (rather than refactoring a complex part of it). "What do you 
want to hear?" I hear you ask. Ok, here is my shameless "since D is supposed to 
be" argument: D is supposed to be pragmatic, so I would start with a collection 
of use cases. Really, "I want attributes to be like this" is not enough. The 
use case should be stated in a fashion, that programmers without experience in 
the field can follow. The standard use cases for attributes are must-haves, the 
rest can be nice-to-haves.

Add to the list, what you need from the attribute system:

** Serialization/RPC **

A relational SQL database comes with meta information on data types. We want to 
annotate D types with the corresponding types in the DB. This can be used to 
validate the value ranges at runtime, generate the correct SQL to work with the 
tables or even create tables that don't exist already. It is also common to 
establish relations between tables. The struct Parent may have a 'Child*[]' 
field and Child a 'Parent*' field.
The same applies to RPC. For example we may want to return a bool[] using a 
special case in the RPC system for bit arrays: '@Rpc(type = 
RpcType.native_bit_array, mode = RpcMode.async) bool[] foo() { … }'. This 
annotation applies to the symbol foo. If make this a more complex return type, 
it becomes this:

        enum RpcMode …;
        enum RpcType …;

        struct Rpc …;
        struct RpcStruct …;
        // has a single field, syntax options:
        // @RpcTypeMap(type = RpcType.int)
        // @RpcTypeMap(RpcType.int)
        // @RpcTypeMap(int) ?
        struct RpcTypeMod { RpcType type };

        @RpcStruct struct MyRet {
                string name;
                @RpcTypeMap(RpcType.native_bit_array) bool[] flags;
        }

        @Rpc(mode = RpcMode.async) MyRet foo() { … }

For RPC it is also necessary, to annotate parameters in the same way:

        void foo(@RpcTypeMap(RpcType.native_bit_array) bool[] flags) { … }


** Edit object properties in a GUI (as suggested by Manu) **

As seen in GUI builders, often the need occurs to generate bindings to data 
structures in order to edit their properties in a convenient user interface. A 
uint field may be edited using a RGB+Alpha color selector and serialized into a 
data file. The requirements for the annotations are the same as above. (I know 
that RTTI would make life easier here, but it isn't a show stopper.)



For these to work it would require:
- user annotations to functions/methods/structs/classes
- only CTFE support (as annotations don't change at runtime)
- no influence on language semantics
And I agree with others that it is a good idea to implement annotations as 
structured types (POD structs at least) to avoid spelling mistakes and 
encourage IDE support. Just as an idea: Such structs, could contain their own 
logic. So some annotations which work stand-alone could validate themselves 
(invariant()?), print debug msgs, write binding definitions to text files (if 
CTFE I/O happens) or actually mixin code if used on structs/classes. But that's 
just brain-storming to give an idea why annotations as key/value pairs could be 
unflexible.
Generally C# and Java annotations have both been a success, so they are both 
what people mostly expect and a good 'template' for D aside from runtim vs. 
compile-time issues.

thanks for reading :)

-- 
Marco

Reply via email to