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.