On Thursday, 6 September 2018 at 10:18:43 UTC, Josphe Brigmo wrote:

Variants can hold an arbitrary set of types.

I imagine that it is effectively just a type id and an object pointer!?

It's a typeid and a static array large enough to hold any basic builtin type: the now-deprecated creal, a dynamic array, or a delegate.

If you make a Variant from an object, it stores that object reference. The object reference is just a pointer, yes.

If you make a Variant from a 256-byte struct, it copies that struct onto the heap and stores a pointer.

If you make a Variant from a 6-byte struct, then it stores that struct and does no heap allocations.

If so, then it really is just a special type of a class class.

It's similar to a java.lang.Object with explicit boxing, but without the need to create a new wrapper class for each value type.

It seems that variant and oop are essentially the same thing, more or less, as whatever can be done in one can effectively be done in the other, except, of course, that the class version has compile time type information associated with it, which sort of restricts variant to a subset of all types!?!

Object-oriented programming includes inheritance and member function overloading. Variant doesn't; it's just about storage.

If you're working with classes, you'd be better off using a base class or interface instead of Variant for fields that can only hold objects of those types.

But variant can reduce the code complexity if one restricts it's inputs to a specific class of types:

Yes, for which you can use std.variant.Algebraic. For instance, Algebraic!(int, long, float) will accept ints, longs, and floats, but nothing else.

Then VariantClass will prevent any arbitrary type from being assigned to the variant, effectively allow inheritance to be used(in the sense that it will prevent any type from being used at compile time, like inheritance):

VariantClass!X v; // only T : X's are allowed.

That's equivalent to `X v;` except with a wrapper around it.

Matching then is dispatch. We could further extend VariantClass to return specific classes for each type that dispatch to match and vice versa.

I think you're saying that this sort of Algebraic could expose any methods and fields common to all its types?

Can D project interfaces like this?

interface I
{
   int foo(int);
}

I i = project!I(o);

You can write code to make that work. It would create a wrapper class that implements the requested interface, and that wrapper would just forward everything to the wrapped value.

It would be a lot easier just to have the type implement the interface itself, if that's possible.

Seems though this cannot be used at runtime though since function signatures are not transported in the binary? If they are, then maybe it would work and would reduce the overhead of oop as one could just project types to other types that overlap.

You can use the witchcraft library on dub to perform runtime introspection, but there would be a performance penalty.

Reply via email to