On Sunday, 3 June 2018 at 16:36:52 UTC, Simen Kjærås wrote:
On Sunday, 3 June 2018 at 14:57:37 UTC, DigitalDesigns wrote:
On Sunday, 3 June 2018 at 09:52:01 UTC, Malte wrote:
You might want to have a look at https://wiki.dlang.org/Dynamic_typing This sounds very similar to what you are doing. I never really looked into it, because I prefer to know which type is used and give me errors if I try to do stupid things, but I think it's a cool idea.

No, this is not what I'm talking about, although maybe it could be related in some way.

Actually, it sort of is. Your mapEnum is essentially the same as std.variant.visit (https://dlang.org/phobos/std_variant#.visit), and std.variant.Algebraic is the type that encapsulates both the runtime tag and the void[] containing the data of unknown type.

Now, there may be many important differences - Algebraic encapsulates the data and tag, which may or may not be what you want, visit only takes one algebraic argument, mapEnum may be faster, more or less generic, etc. The idea of converting a run-time value to a compile-time value is the same, though.

--
  Simen

I didn't know that variants had those functions! pretty nice. Yes, it is similar to what I'm doing. Same principles but just a little different perspective. I use enums, UDA's, and templates rather than a Algebraic and delegates.

The difference is that the enum stores only the type information rather than the variable and the type info that Algebraic stores.

If I were to have know about this before I might have used it instead and everything would have probably been fine.

The only thing is that the enum version lets me store the type info separately than with the data. When several variables depend on the type id I think it will make it a little easier than having to manage several Algebraic type info's across several variables to sync them.

For example

dataType type;
void[] in, out;

rather than

Algebraic!(type1,..., typen) in, out;

and then having to make sure the types are synced between in and out. At least in my case it might be a little easier. Also my way uses a templated function directly rather than an array of lambads, although they are equivalent:

Algebraic!(string, int) variant;

variant.visit!((string s) => cast(int) s.length, (int i) => i)();

which could be written as

variant.visit!((string s) => foo(s), (int i)    => foo(i))();

auto foo(T)(T t) { }


would become

enum variant
{
    @("int") _int,
    @("string") _string,
}

mixin(variant.MapEnum!("foo")());

auto foo(T)(T t) { }


So, they definitely are very similar and actually might be identical. I haven't used Algebraic and visit any to know.

What I do know is that for several Algebraics you would have to do something like

variant.visit!((string s) => variant2.visit!((double d) => { foo(s,d); })), (int i) => foo(i))();

etc. Which is creating the nested switch structure and can become complicated while my method still remains one line but foo just takes more than one template parameter. My feeling is mine is a little less robust since it's more for specific types of code while visit is a little more general. Mainly because of the hard coding of the mixin structure.




Reply via email to