Objective-D, reflective programming, dynamic typing

grauzone none at example.net
Sat Apr 4 11:43:50 PDT 2009


Andrei Alexandrescu wrote:
> grauzone wrote:
>> Andrei Alexandrescu wrote:
>>> Georg Wrede wrote:
>>>> Andrei Alexandrescu wrote:
>>>>>
>>>>> void foo_templated(T...)(T args)
>>>>> {
>>>>>    Variant[args.length] dynatyped;
>>>>>    foreach (i, arg; args) dynatyped[i] = arg;
>>>>>    return foo(dynatyped);
>>>>> }
>>>>> void foo(Variant[] dynatyped...)
>>>>> {
>>>>>    ...
>>>>> }
>>>>
>>>> Hmm. An idiom. My sweet tooth just got thirsty for syntactic sugar!
>>>
>>> When opImplicitCastFrom will be implemented, foo's definition will be 
>>> enough. You'll write foo(1, 2.3, "a") and the compiler will rewrite 
>>> it to foo(Variant(1), Variant(2.3), Variant("a")).
>>
>> This looks very good. How exactly will it work?
> 
> Variant will implement opImplicitCastFrom(T) for all types T. The "..." 
> in foo's declaration already allows variadic arguments. The rest will be 
> taken care of by the compiler.

I see.

Consider if opImplicitCastFrom was implemented and you had a function 
"void foo(Variant[] x...)", would it be possible to pass a Variant[] to 
it, that will be directly used as "x"?

For example:

void foo(Variant[] x...) {
	writefln(x);
}

Variant[] t = [1,2,3];
foo(t);

Possible output 1:
[1, 2, 3]

Possible output 2:
[[1, 2, 3]]

This is a slight ambiguity. Will "t" be packed into a Variant, or will 
it directly assign "t" to "x" as if there wasn't an 
opImplicitCastFrom(T)? Would it be a compilation error?

Anyway. If this would work, chaining function calls would be simple, and 
wouldn't require additional wrapper functions.

> So IMHO:
> 
> (a) Variadics with templates are good;

The "void foo(Variant[] dynatyped...)" isn't a template. But if on the 
caller side you can use it as if it was a "void foo(T)(T...)" or a "void 
foo(...)", everything is fine.

> (b) Variadics with uniform-type arrays are good;

Sure.

> (c) We should avoid variadics with void*.

Well, it isn't really important whether you use a (TypeInfo, void*) 
tuple, or a Variant for passing around data of a dynamic type unknown at 
compile time. Of course, Variant is much nicer.

I was only suggesting void*, because for classic variadics, it's 
probably simpler to implement on the compiler side. (Although, as you 
said, it's hard to convert a (TypeInfo, void*) to Variant.)

> 
> Andrei



More information about the Digitalmars-d mailing list