Time for std.reflection

Manu turkeyman at gmail.com
Mon Nov 19 16:58:26 PST 2012


Huge interest!
I wouldn't want to see static data structures bloat/clutter the exe though
in cases where it's not ever used/queried.
The object factory is already a serious problem.


On 22 July 2012 00:44, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>wrote:

> Walter and I discussed the idea below a long time (years) ago. Most likely
> it's also been discussed in this newsgroup a couple of times. Given the
> state of the compiler back then, back then it seemed like a super cool idea
> that's entirely realizable, it would just take time for the compiler to
> become as capable as needed. Nowadays we're in shape to tackle it.
>
> Here "it" is.
>
> Back when runtime reflection was being discussed, my response was "let's
> focus on compile-time reflection, and then we can do run-time reflection on
> demand as a library". Though this might sound sensible, I initially didn't
> have a design. Now here's what we can do.
>
> Currently we have information about symbols as __traits(...) intrinsics
> wrapped in nice but scattered ways. Now that CTFE is good enough to
> manipulate structs and arrays thereof, we have the possibility to finally
> approach things in a nicely unified, structured way.
>
> First, we need to prime std.reflection with a few abstractions that
> characterize entities in a D program.
>
> class ModuleInfo {
> @property:
>     string name();
>     ImportInfo[] imports();
>     DataInfo[] data();
>     FunctionInfo[] functions();
>     ClassInfo[] classes();
>     StructInfo[] structs(); // includes unions
>     TemplateInfo[] templates();
>     EnumInfo[] enums();
>     bool hasStaticCtor(), hasStaticDtor(),
>       hasSharedCtor(), hasSharedDtor();
> }
>
> Probably there are a few more pieces of data, but you get the idea. Then
> for each of the entities mentioned above we have a similar definition. For
> example:
>
> enum Protection { isPublic, isPackage, isProtected, isPrivate }
>
> class ClassInfo {
> @property:
>     string name();
>     string baseName();
>     string parentName(); // if applicable, null otherwise
>     string[] interfaces();
>     bool isShared();
>     Protection protection();
>     DataMemberInfo[] data();
>     MethodInfo[] methods();
>     Object defaultConstructor();
>     ...
> }
>
> Then for an e.g. method declaration we'd have:
>
> class MethodInfo {
> @property:
>     string name();
>     bool isStatic(), isFinal(), isOverride();
>     Protection protection();
>     string[] parameterTypes();
>     string[] parameterNames();
> }
>
> Some details may vary, e.g. some may be straight members instead of
> properties etc. (I used properties to allude to use of lazy gathering of
> information).
>
> So so far we have a nice collection of structured data associated with the
> entities in a D program. Note how this structuring differs yet has similar
> power to the primitives in std.traits; std.traits offers unstructured bits
> of information on demand (e.g. ParameterTypeNames) etc. but the objects
> above group information together per entity declared. All of the above goes
> in std.reflection, of course.
>
> ===========
>
> On to primitives that return such data.
>
> Given that D can (since relatively recently) create and manipulate class
> objects during compilation too, it follows that the classes above can be
> accessed in two ways - through compile-time API and run-time API. When
> possible, the APIs may even use the same functions; some other times they
> will be necessarily different.
>
> There are two possible approaches to discovering such information. One is
> by fetching the ModuleInfo for the whole module and navigating it. Another
> one is by using search primitives from strings.
>
> So we should have e.g.
>
> // inside std.reflection
> ModuleInfo getModuleInfo(string moduleName);
>
> so a CT call would go like:
>
> // client code
> static info = getModuleInfo("std.algorithm")**;
>
> whereas a run-time call would be:
>
> // client code
> auto info = getModuleInfo("std.algorithm")**;
>
> In the latter case, the module needs to save all needed information for
> ri, so it should plant this:
>
> // inside std.algorithm
> mixin(**makeModuleInfoAvailableDynamic**ally());
>
> The mixin would generate all information needed and would store it for
> later dynamic use.
>
> A search API would go like e.g.
>
> ClassInfo getClassInfo(string className);
>
> In this case the class name could be qualified with module information etc.
>
> ===========
>
> With this design we unify compile-time and run-time type manipulation in
> simple ways, by defining structured information about declarations that can
> be queried during compilation or dynamically.
>
> Please chime in with thoughts. Would someone want to pioneer this project?
>
>
> Andrei
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20121120/0b50648d/attachment.html>


More information about the Digitalmars-d mailing list