Dynamic D

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Jan 6 10:24:37 PST 2011


On 1/6/11 11:52 AM, Robert Jacques wrote:
> 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].

I think Variant should default to holding "void".

> 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.

That's great, but (a) that's again outside what Variant is supposed to 
do, and (b) for JSON we're dealing with a closed hierarchy which 
suggests a different design.

>> * 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.

Algebraic with the fundamental JSON types is a great example because 
they all may share certain methods. Generally Algebraic with closed 
hierarchies (e.g. Visitor) are good candidates for the feature. Of 
course, if that feature affects other functionality we should avoid it. 
It's just "nice to have".

>> * 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.

Great. Why not call it "Dynamic"?


Andrei


More information about the Digitalmars-d mailing list