Compiler patch for runtime reflection

Robert Jacques sandford at jhu.edu
Thu Oct 27 09:49:06 PDT 2011


On Wed, 26 Oct 2011 14:20:47 -0400, Jonny Dee <jonnyd at gmx.net> wrote:
[snip]
> Am 26.10.11 07:16, schrieb Robert Jacques:
[snip]
> I've got no problem with an approach which puts runtime reflection
> capabiities into a separate library. No matter were you look at, Java,
> C#, or Qt, all have a library for reflection purpose. I do not see,
> however, how this might be done without compiler support.

Long ago, when reflection in was being discussed one of the big reasons we turned to compile-time reflection first, besides its synergy with other meta-programming features, is because compile-time reflection enables runtime-reflection. A decent portion of the community has always assumed that D's runtime reflection support would come from a library exploiting D's compile-time reflection. All it would take is someone willing to put in the effort and time to do so. So far, that someone has been me. :)

My new Variant (https://jshare.johnshopkins.edu/rjacque2/public_html/variant.mht) makes heavy use of compile-time reflection and provides runtime-reflection capabilities. Currently, I have focused on dispatch, i.e. the calling of member functions, the calling of static members and the setting of fields, as I don't know what the introspection API should look like. I have found that while __traits does provide all the information I need, it's often not in the format I wish to consume it in. So I have been holding back on implementation in order to solicit the feedback of the community.

As for ease of use, Variant generates reflection information for every type it is exposed to. That includes all return types, fields and member arguments types for every type assigned to or retrieved from Variant. Most of the time, exposure happens naturally and everything 'Just Works' and no effort is needed. For example:

Variant var = student;
assert(var.grade.mark == student.grade.mark)

Or

Variant var = Object.factory("example.Student");
assert(var.grade == (var.get!(Student)).grade);

Now it is possible for types, particularly sub-classes, to never be retrieved from or assigned to, in which case only they can only use their interfaces/base-classes type information, without some form of registration. For example,

Variant.__register!Student;

And with the new module reflection capabilities, the hassle / annoyance of registration can be reduced to that of an import statement. Or even a single statement that would reflect all the imports in a module. (Registration works via static ctors, so their's no worry about using reflection before registration, or duplicate registrations, etc)

Now, this probably gets to the heart of why I don't like the concept of @noreflect, @reflect or any other fixed reflection option: there is no right answer to whether or not a class should support reflection. Trying to find a single choice (or all/none) that fits the embedded, iOS/Driod/Windows 8, Desktop, Server, etc developer is fool hardy. Letting each developer choose how much or how little they need feels right to me. And in D we have the tools to provide the granularity of control to make this declaration of reflection intent as succinct as possible.


More information about the Digitalmars-d mailing list