Time for std.reflection

Philippe Sigaud philippe.sigaud at gmail.com
Sun Jul 22 23:30:48 PDT 2012


On Sun, Jul 22, 2012 at 4:28 PM, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:

> std.reflection could become the lynchpin for dynamic library use; once the
> library is loaded (with dlopen or such), the client needs to call
> getModuleInfo() (a C function that can be found with dlsym()) and then get
> access to pointers to functions necessary for doing all other work. (Note
> that my examples don't yet include pointers to executable code yet.)

I wouldn't know. I have no experience with dlsym().

>> 2) Why classes, as opposed to structs? Would inheritance/hierarchies
>> play a role there? Or reference semantics?
>> Note that between structs, classes, templates and modules there is a
>> lot of redundancy. A possibility could be to have an AggregateInfo
>> base class.
>
>
> Initially I used struct, but then I figured reference semantics are more
> natural for storing cross-entity information, as you indeed took advantage
> of in your TemplateInfo.

I realized a few minutes after posting I answered my own question:
because this is a self-referencing structure (a tree, a graph), which
are easier to code with classes than structs.


>> 4) How would that allows queries like "Here is class C, give me all
>> its available subclasses."? Hmm, wait, I get it: extract classes from
>> the module, and recursively from imported modules. From these classes,
>> extract the parent classes and so on, until the search ranged over the
>> whole inheritance tree. I guess inheritance info could be standard
>> enough for std.reflection to provide such a search.
>
>
> Something like that. Note that such a query is not particularly OO-ish,
> because getting a class' cone (totality of subclasses) works against the
> modularity that inheritance is meant for. I don't think we should make
> getting class cones particularly easy.

Right. Since people here asked this question, I thought that was a
common request in OO. I'm more a structs and mixins guy, myself.


>> 5) The compiler can emit JSON output giving a partial view of the same
>> information. As a long-term goal, I suggest these infos should be
>> compatible somehow. The JSON output should be enriched, and we should
>> ascertain that using std.json to read this kind of
>> automatically-generated information should give std.reflection infos
>> back.
>
>
> Yes, that's a great connection that Walter and I discussed a bit.

Good to know.


>> 6) Is really all the necessary info available through std.traits and
>> __traits? Imported modules and their subtilities (renamed functions,
>> etc) seem out of reach, no?
>
>
> We'll need indeed to enhance __traits with what's needed. Much of the point
> of std.reflection is to determine exactly what's there and what's needed.
> And that starts with the data structures design (the algorithmic aspects are
> minor).

+1 for enhancing __traits locally.

- having __traits(allMembers, xxx) work on simple module names, and
not only on qualified package.module names
- having a way to get imports and a way to know whether they are
static / renaming import


As for the data structures, other people's designs allured to in this
thread seem similar to your proposal.

I have two other questions:

About functions: should they be subject to reflection also, or not?
They have no fields, inner functions are totally interned, etc. All a
user need is the 'interface', right? (name, and everything that's in
the type: return type, parameters, purity, etc)

About imports, what about inner imports, now that they are authorized
in almost any scope? My gut feeling right now is that a user does not
care if class C internally import std.algorithm in one of its methods,
but I could be wrong.


>> 7) I know your examples are not complete, but don't forget aliases and
>> symbols, and module-level values. Since these can be of any type, I'm
>> not sure how they are managed in your scheme. I mean, you cannot have
>> IntInfo[], DoubleInfo[], ...
>
>
> I sort of eschewed part of that by using strings for types.

I see. They can be managed like fields in an aggregate (struct /
classes), as there are many similarities between D modules and classes
/ structs.

class ModuleInfo {
@property:
...
   FieldInfo[] data; // also used in StructInfo and ClassInfo
}

class FieldInfo {
@property:
    string name();
    bool isStatic();
    Protection protection();
    string type();
}

As long as this info is available at CT, FieldInfo.type can be
mixed-in and used in code.

what I'm not sure I get in your design is why some informations are
encoded in their own structure, like Protection above (the code is
copy-pasted from yours, I'd guess Protection is an enumeration), and
then some others are encoded as strings (types). Is that because the
values Protection can take are known in advance (and finite)?

I wondered whether a design like this could be interesting?:

abstract class FieldInfo {}

class Field(T) : FieldInfo {
@property:
    string name();
    bool isStatic();
    Protection protection();
    alias T Type;
}

But that doesn't cut it, AFAICT: different fields can be stored in a
FieldInfo[] array, but the type information is not easier to get,
anyway. So forget it.


This kind of manipulation is why I got interested in fully polymorphic
trees (tuples of tuples...), able to store any value, while keeping
the type information visible. The drastic consequence is to have a
tree type depend on its entire content. But I'm coming from Static
Typing Land here, whereas this introspection stuff is more dynamic.

Anyway, back to gobal values: aliases should be there also. A simple
AliasInfo class?


> Well you're the resident crazy-stuff-during-compilation guy.

Ah! I wish.

I had this wonderful idea of having code be parsed at CT, semantically
analyzed, transformed into some machine code at CT and... , oh wait.


> Did you try your trees during compilation?

Just did. They fail :) Either segmentation fault (core dumped) or an
error telling me class literals  cannot be returned from CTFE.
Hmm, this is old code. I'll have a look since in other projects, I can
obtain trees at CT.


Philippe


More information about the Digitalmars-d mailing list