Need runtime reflection?

David Piepgrass qwertie256 at gmail.com
Tue Jul 17 08:08:16 PDT 2012


> I want to imitate golang's interface in D, to study D's 
> template. I wrote
> some code: https://gist.github.com/3123593
>
> Now we can write code like golang:
> --
> interface IFoo {
>     void foo(int a, string b, float c);
> }
>
> struct Foo {
>     void foo(int a, string b, float c) {
>         writeln("Foo.foo: ", a, ", ", b, ", ", c);
>     }
> }
>
> struct FooFoo {
>     void foo(int a, string b, float c) {
>         writeln("FooFoo.foo: ", a, ", ", b, ", ", c);
>     }
> }
>
> GoInterface!(IFoo) f = new Foo;
> f.foo(3, "abc", 2.2);
>
> f = new FooFoo;
> f.foo(5, "def", 7.7);
> --
>
> It is also very naive, does not support some features, like 
> out/ref
> parameters, free functions *[1]* and so on. The biggest problem 
> is downcast
> not supported. In golang, we can write code like*[2]*:
> --
> var p IWriter = NewB(10)
> p2, ok := p.(IReadWriter)
> --
>
> Seems [p.(IReadWriter)] dynamically build a virtual table 
> *[3]*,because the
> type of "p" is IWriter, it is *smaller* than IReadWriter, the 
> cast
> operation must search methods and build vtbl at run time.
>
> In D, GoInterface(T).opAssign!(V)(V v) can build a rich runtime 
> information
> to *V* if we need. But if *V* is interface or base class, the 
> type
> information not complete. So, seems like I need runtime 
> reflection? and how
> can I do this in D? I did not find any useful information in 
> the TypeInfo*.
>
> ------
> [1] free functions support, e.g.
> --
> interface IFoo {
>     void foo(int a, string b, float c);
> }
> void foo(int self, int a, string b, float c) {
>     writefln("...");
> }
>
> GoInterface!(int) p = 1;
> p.foo(4, "ccc", 6.6);
> --
> In theory no problem.

I, too, was enamored with Go Interfaces and implemented them for 
.NET:

http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language

And I wasn't the only one; later, someone else published another 
library for .NET with the exact same goal. This is definitely a 
feature I would want to see in D, preferably as a first-class 
feature, although sadly that would break any code that relies on 
ISomething being pointer-sized; Go uses fat pointers, and we use 
a thin-pointer implementation in .NET but it's inefficient (as 
every cast creates a heap-allocated wrapper, and 
double-indirection is needed to reach the real method.)

Anyway, they say it's possible to build runtime reflection in D 
but I've no idea how... has it never been done before?

Of course, runtime template instantiation won't be possible. 
Therefore, run-time casting will have to be more limited than 
compile-time casting.

Reflection to free functions would be really nice, but it might 
be less capable at run-time. Consider if you there is a class A 
in third-party module MA that you want to cast to interface I, 
but class A is missing a function F() from I. So in your module 
(module MB) you define a free function F(B) and now you can do 
the cast. I guess realistically this can only happen at 
compile-time, since a run-time cast would naturally only look in 
module MA, not MB, for functions it could use to perform the 
cast. Presumably, it also requires that MA requested a run-time 
reflection table to be built, and is it possible to build a 
reflection table for a module over which you have no control?



More information about the Digitalmars-d mailing list