On Wednesday, 9 March 2016 at 12:55:16 UTC, Idan Arye wrote:
Allowing something like `auto params = [:y : 50, :x : 100]` won't really solve anything. It works nicely in Ruby, because Ruby has dynamic typing and with some syntactic sugar you get elegant syntax for dynamic structs. But in a structured language like D, you run into the problem that `[:y : 50, :x : 100] is an associative array with a determined type for it's values, so you can't do things like `[:y : 50, :x : "hello"]` - which greatly limits the usability of this syntax.

I posted (in a previous thread about this issue) a library solution to this:

import std.typecons, std.meta;
private struct Named(string n, T) {
    enum name = n;
    T value;
}
template NamedToAS(N...) {
    static if (N.length == 0) {
        alias NamedToAS = AliasSeq!();
    }
    else {
alias NamedToAS = AliasSeq!(typeof(N[0].init.value), N[0].name, NamedToAS!(N[1 .. $]));
    }
}
struct Tup {
    static auto opDollar(size_t i)() {
        return immutable KeyWordDollar();
    }
    static auto opIndex(NamedArgs...)(NamedArgs nas) {
        Tuple!(NamedToAS!NamedArgs) tup;
        foreach(i, ref na ; tup) {
            na = nas[i].value;
        }
        return tup;
    }
}
void overrideFrom(TupDef, TupOver)(ref TupDef defaultMap, ref TupOver overrideMap) {
    foreach(i, ref field ; overrideMap) {
__traits(getMember, defaultMap, TupOver.fieldNames[i]) = field;
    }
}
auto println(KWA)(KWA kwa) {
    auto args = Tup[$.str = "abc", $.repeat = 2, $.sep = " "];
    args.overrideFrom(kwa);
    import std.stdio;
    bool first = true;
    foreach(i ; 0 .. args.repeat) {
        if (first) first = false; else write(args.sep);
        write(args.str);
    }
    writeln();
}
unittest {
    println(Tup[$.str = "xyz", $.repeat = 8]);
}

Reply via email to