Custom attributes (again)

Marco Leise Marco.Leise at gmx.de
Sun Apr 8 00:27:32 PDT 2012


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



More information about the Digitalmars-d mailing list