Dynamic D

Robert Jacques sandford at jhu.edu
Thu Jan 6 09:52:08 PST 2011


On Thu, 06 Jan 2011 10:35:07 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:
> On 1/6/11 1:22 AM, Robert Jacques wrote:
>> On Mon, 03 Jan 2011 17:23:29 -0500, Adam Ruppe
>> <destructionator at gmail.com> wrote:
>>> Over the weekend, I attacked opDispatch again and found some old
>>> Variant bugs were killed. I talked about that in the Who uses D
>>> thread.
>>>
>>> Today, I couldn't resist revisiting a dynamic kind of object, and
>>> made some decent progress on it.
>>>
>>> http://arsdnet.net/dcode/dynamic.d
>>>
>>> (You can compile that; there's a main() at the bottom of that file)
>>>
>>> It isn't quite done - still needs op overloading, and probably better
>>> errors, but it basically works.
>>>
>>> It works sort of like a Javascript object.
>>>
>> [snip]
>>
>> I've been working on an update to both std.json and std.variant.
>> Previews of both are available here:
>> https://jshare.johnshopkins.edu/rjacque2/public_html/
>> though they are still works in progress. Two of the big enhancements
>> that you might be interested in are call support and opDispatch +
>> reflection + prototype structs. To paraphrase your example:
>>
>> Variant v;
>> v.a( 10 );
>> assert(v.a == 10);
>> v.a( { writefln("hello, world"); } );
>> v.a.call; //To be replaced by opCall, once struct opCall is fixed (Bug
>> 4053)
>> v.a( delegate void(string a, int x) { foreach(i;0..x) writeln(i+1,"
>> ",a); } );
>> v.a("potatoes", 3);
>>
>> I've also stubbed out a prototype style object, but I haven't really
>> tested it yet. Thoughts, comments and use/test cases are always  
>> welcomed.
>
> I think this transgresses the charter of Variant. Variant is meant to  
> hold an object of some _preexisting_ type, not to morph into anything.  
> We should have three abstractions:

And Variant still only holds an object of some preexisting type. What you  
are seeing is simply syntactic sugar for a Variant of type  
Variant[string]. The above lowers down into:

Variant v;
Variant[string] __temp;
v = __temp;
v["a"] = 10;
assert(v["a"] == 10);
v["a"] = { writefln("hello, world"); };
v["a"].call();
v["a"] = delegate void(string a, int x) { foreach(i;0..x) writeln(i+1,"  
",a); };
v["a"].call("potatoes", 3);

The only morph happens because actually making the Variant default type be  
Variant[string], has some issues (GC interaction, hasValue,  
Variant[string].init isn't usable, etc). So I decided that if and only if  
you used an uninitialized Variant as a Variant[string], it would 'morph'  
to a Variant[string].

As for the v.a -> v["a"] syntactic sugar, I have found it very useful in  
the parsing/use of dynamically structured structs, including JSON.

> * Algebraic holds any of a closed set of types. It should define method  
> calls like a.fun(args) if and only if all of its possible types support  
> the call with compatible arguments and return types.

I have considered this, but while this concept looks good on paper, in  
practice it cripples Algebraic. The issue is that the intersections of  
types tend to have no methods/operators in common. For example,  
Algebraic!(int,string) would have no methods nor operators defined.

> * Variant holds any of an unbounded set of types. Reflection may allow  
> us to define v.fun(args) to look up the method name dynamically and  
> issue a runtime error if it doesn't exist (sort of what happens now with  
> operators).

It's not 'may' anymore. Reflection _does_ allow me to define v.fun(args)  
to look up the method name dynamically and issue a runtime error if it  
doesn't exist. eg:

     class Foo { real x = 5; }
     auto foo = new Foo;
     Variant a = foo;
     assert(a.x == 5);             // perform runtime reflection on 'a'  
implicitly
     a.__reflect("x",Variant(10)); // or explicitly
     assert(a.__reflect("x") == 10);	

> * Dynamic is a malleable type that you get to add state and methods to,  
> just like in Javascript.

And I have stubbed out a Prototype object for just this reason.


More information about the Digitalmars-d mailing list