March 01, 2018
Not very important, but I was reminded of a few things yesterday while filling out the survey.

1) I remember reading somewhere a long time ago that __traits had that ugly name because it wasn't supposed to be used directly; you'd instead generally use something nicer like std.traits (or maybe I'm misremembering the argument for naming __gshared). But many of things that you can do with __traits still aren't in std.traits. Is this intentional, or is there a will to make std.traits the go to place for all things traity? BTW, one advantage of using std.traits instead of equivalent __traits is that you can use UFCS.

2) I also remember when I first used __traits allMembers that I was surprised it returned strings instead of references to the members. First of all, it's not named allMembersStrings. Second, it seemed like if you wanted a string you could use .stringof or something similar, and getting the member itself was the normal case, so what you'd optimize for. In any case, even if the __trait itself is never changed, that's probably a case where we could add a higher-level wrapper in std.traits that returns the references. Related to that, I saw this code mentioned in the d-idioms:

BuildSettings dup() const
{
    BuildSettings ret;

    foreach (m; __traits(allMembers, BuildSettings))
    {
        static if (is(typeof(__traits(getMember, ret, m) = __traits(getMember, this, m).dup)))
            __traits(getMember, ret, m) = __traits(getMember, this, m).dup;
        else static if (is(typeof(__traits(getMember, ret, m) = __traits(getMember, this, m))))
            __traits(getMember, ret, m) = __traits(getMember, this, m);
    }
    return ret;
}

This is pretty intimidating code (and ugly IMO) for someone who isn't very familiar with the more advanced D features. I think what makes this harder to read for the uninitiated is that it's directly written in terms of lower-level features, instead of using nicer wrappers like hasSomeProperty!X. The wrapper has the advantage of both documenting the intent and making it easier to study how SomeProperty is detected using __traits, since you aren't simultaneously trying to understand *what* the code is testing and *how*. Documenting the intent in terms of a wrapper also makes it easier to catch bugs in code review, without having having to add actual code comments.