Dynamic D

Adam D. Ruppe destructionator at gmail.com
Mon Jan 3 20:27:16 PST 2011


spir wrote:
> obj.a() = { writefln("hello, world"); }
> is a real mystery for me ;-)

Yea, like Robert said, what happens is the opDispatch method
(which turns the part after the string into a template parameter
instead of a compile error, see:
http://digitalmars.com/d/2.0/operatoroverloading.html#Dispatch
for more info) just returns a reference to the property.

Each property has the same type as everything else - struct Dynamic.
It's opAssign takes arbitrary types, wraps them if necessary,
and stores a reference to the wrapper function.


You'll notice that every time I create one of these internally,
I go through the extra step to new it on the heap. I got some
random segfaults before, because a stack allocated object gets
wiped out when the function returns (possibly a bug in dmd's
closure detection algorithm, but maybe not, since this behavior
is expected coming from C, C++, D1, etc). Anyway, I want to keep
the intermediates around in case they are used later by a ref
return somewhere and the new keyword ensures exactly that.

Actually I think I want Dynamic to be a class instead of a struct
so it is always by reference, but that might be weird too. I don't
know for sure yet.

The wrapper function is created by the method makeDynamic. It
returns a delegate that makes the static parameter list out
of the dynamic arguments. I used this same technique in my web.d
to automatically call D functions from cgi parameters - it generates
a wrapper function that takes string[string] and converts it to
the static type, by looping through and calling to!type on each
string.

(This looked a bit weird the first time I did it too - it doesn't
loop the dynamic args, but instead the static args. The reason is
the static arguments, via std.traits.ParameterTypeTuple, can be
worked with as static types and passed to other templates, like
std.conv.to. A dynamic type can't.

Basically if you know what to expect, you can work with the
compiler, but if you don't, it is guess and check. This comes
up again later.)


Anyway, the reference to that wrapper function is what's stored.
This is advantageous because then all methods you assign have
a uniform signature - suitable for a runtime array.


> Main difference is that (unlike prototype-ba sed ones like JS,
> Io, etc) inheritance is not done via delegating but by plain
> copy of (references to) methods.

That could be done from inside D too! In fact, it might make
sense here. But maybe not, since the this for the wrapper functions
(which you'd actually be passing around) would get weird.

I'd have to play with it, but I'm pretty confident D could do
it itself - no need to make a new toy language!

> Also, there would be some kind of type, again unlike true
> prototype-based, but they would really be true objects, like
> when writing a simple OO typing system in Lua.

I've never actually used Lua, but the concept sounds simple
enough. I think it'd be a fairly small modification of where
I'm taking my code.


More information about the Digitalmars-d mailing list