Typed annotations proposal



Hi hackers,

this goes to introspection support bug
(http://bugzilla.gnome.org/show_bug.cgi?id=139486 ). I've recently added
new file (metadata-annotations-proposal.txt) to gobject-introspection
module in cvs which contains first draft of proposal. In this mail, I
present some questions and outstanding issues that need to be addressed,
as well as answer some of Matthias's questions (you can see them as
comments in that file).

First, what is this all about? In current spec annotations are simply
strings. This proposal seeks to introduce typed annotations, that is,
make them instances of of proper GTypes (with some restrictions, see
below). This allows to put more useful info into annotations, and
effectively creates way to extend stored metadata without changing spec.
I should also note all this is heavily inspired by the way .NET does
attributes.

Proposed way splits annotations into 2 (3, in fact) parts:
AttributeBlob, which defines type (it's to annotation what class is to
object), and actual AnnotationBlob(s), which introduce specific
instances of given attribute. There's also 3rd part, the value of
annotation, that is contigous block of raw bytes to be read as n fields
(described by AttributeBlob), concatenated together with appropriate
padding inbetween. It should be noted that annotations are introduced at
compile time, and thus need to be completely statically defined.

Because annotations need to be fully static, AttributeBlobs are
restricted to be series of fields, and each field must evaluate to
literal expression. This allows you to define fields of usual types for
which literal expressions exist, as well as additional "type" type.
"type" is reference to another type in metadata; it is intended for
things like, for instance, container specialisation, marshalling, etc.

Also, Attributes can specify valid targets to which they can be applied.
Rationale behind it is that some attributes make sense only in certain
context, for example if you had UnitTestMethodAttribute (akin to what
NUnit testing framework for .NET does), you only want it to apply to
methods. Similarly, SerialisableAttribute (useful for IPC) would be
applied on per-type basis. Matthias has some doubts about usefulness of
restricting targets, personally I think it's kind of type-checking
safety means, however I'm not gonna fight very much over it :). To
answer another related Matthias's question, "all" means all of the
above, not any blob.

Now for the questions & issues:

1) How do we mark what annotations apply to given metadata entry?
Current spec says that we have annotations pool, sorted by offset of
entry to which they apply, however this is completely unsupportable by
dynamic languages, as you generate metadata as you go. In general,
current spec isn't very friendly towards anyone who would want to
generate metadata dynamically, but here it's especially visible. 

One solution is to add offset to annotations to each metadata entry that
can be annotated, however that means additional 4 bytes for every such
entry, in particular, each type, function and param. Clearly it isn't
good, as it would blow the size of metadata out of proportion.

What .NET does in their assemblies it to keep sort-of mini relational
database table, where there's attribute instance and then all the
entries to which it applies. This looks somewhat useful, however it'd
need more careful analysis as to how it'll behave in context of fully
dynamic data generation.

2) Constructors and inheritance. It is intended that Attributes will be
registered GTypes (not GObjects, though). I think it makes sense to make
them inheritable, too (the question if we have common base type remains
open, we could introduce it to make it easier for language runtimes to
support defining attributes like ordinary types). Also, currently
proposal allows them to have constructors. This would make it possible
to perform some sort of transformation before initialising fields (like
name mangling, etc.). Again this is taken directly from .NET, where you
can have constructor (with arguments). 

In .NET, initialisation order is that first constructor is run with
positional parameters, next all optionals keyword params (of name =
value form, given after positional parameters for constructor) are read
as initalisers for attribute fields, and then all not yet initialised
fields are assigned default value.

This of course introduces additional complexity, as annotations are no
longer static, only have static initaliser list, requiring us to spec
out details of construction and lifetime. If this is deemed not useful,
or not worthy, we can safely drop constructors support.

3) Related to the above, should the annotations be mutable? And should
we allow to annotate user variables? This is large part of annotations
usage in .NET world, however it doesn't really work unless you have
common runtime, adds lots of complexity, and we have g_object_set_data()
anyway, so it doesn't seem very useful.

4) In 2), I mention that fields that aren't explicitly given value get
default. Well, except that we don't currently have any way to express
default value. This needs addressing, and language bindings will need
that to support default function parameters anyway.

I think that's all I can remember right now, please discuss and comment.

Cheers,
Maciej

-- 
Maciej Katafiasz <ml mathrick org>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]