www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Just a few thoughts on traits

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.
Mar 01 2018