www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Fun with allMembers

reply Shin Fujishiro <rsinfu gmail.com> writes:
Hi,

I've had fun with the allMembers traits over the past few days and found
it more powerful than I thought.

__traits(allMembers, T) returns the member names of T. As some might
already know, T is not restricted to a class or struct; it can also be
an enum, template, or even module. Try this:
--------------------
enum E { a, b, c }
template T() { int x, y, z; }
import std.stdio;
pragma(msg, __traits(allMembers, E).stringof);
pragma(msg, __traits(allMembers, T).stringof);
pragma(msg, __traits(allMembers, std.stdio).stringof);
--------------------
You'll like the result :). It must be usable!

For example, using allMembers with enums, I could implement
enumToString and enumFromString without defineEnum.
Code: http://codepad.org/HVvPjoI7

So, what other uses could there be?
May 13 2009
next sibling parent reply Sam Hu <samhudotsamhu gmail.com> writes:
Powerful ...but in my pc the output is :

["a","b","c"]
["x","y"]      //====>not ["x","y","z"]???
["object","core",...]
May 13 2009
parent Sam Hu <samhudotsamhu gmail.com> writes:
Solved.
May 13 2009
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Shin Fujishiro wrote:
 Hi,
 
 I've had fun with the allMembers traits over the past few days and found
 it more powerful than I thought.
 
 __traits(allMembers, T) returns the member names of T. As some might
 already know, T is not restricted to a class or struct; it can also be
 an enum, template, or even module. Try this:
 --------------------
 enum E { a, b, c }
 template T() { int x, y, z; }
 import std.stdio;
 pragma(msg, __traits(allMembers, E).stringof);
 pragma(msg, __traits(allMembers, T).stringof);
 pragma(msg, __traits(allMembers, std.stdio).stringof);
 --------------------
 You'll like the result :). It must be usable!
 
 For example, using allMembers with enums, I could implement
 enumToString and enumFromString without defineEnum.
 Code: http://codepad.org/HVvPjoI7
 
 So, what other uses could there be?

Wow, I didn't know about this! It might as well be everything needed for a full-blown compile-time reflection package! To answer your question: for starters, try to implement BlackHole and WhiteHole as explained here: http://erdani.dreamhosters.com/cranking-policies-up.pdf Andrei
May 14 2009
next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

 Shin Fujishiro wrote:
 Hi,
 
 I've had fun with the allMembers traits over the past few days and found
 it more powerful than I thought.
 
 __traits(allMembers, T) returns the member names of T. As some might
 already know, T is not restricted to a class or struct; it can also be
 an enum, template, or even module. Try this:
 --------------------
 enum E { a, b, c }
 template T() { int x, y, z; }
 import std.stdio;
 pragma(msg, __traits(allMembers, E).stringof);
 pragma(msg, __traits(allMembers, T).stringof);
 pragma(msg, __traits(allMembers, std.stdio).stringof);
 --------------------
 You'll like the result :). It must be usable!
 
 For example, using allMembers with enums, I could implement
 enumToString and enumFromString without defineEnum.
 Code: http://codepad.org/HVvPjoI7
 
 So, what other uses could there be?

Wow, I didn't know about this! It might as well be everything needed for a full-blown compile-time reflection package! To answer your question: for starters, try to implement BlackHole and WhiteHole as explained here: http://erdani.dreamhosters.com/cranking-policies-up.pdf Andrei

See also this article from the author of PyD: http://kirkmcdonald.blogspot.com/2007/07/inadequacies-of-traits.html (Not that it isn't very powerful as is.)
May 14 2009
prev sibling parent Georg Wrede <georg.wrede iki.fi> writes:
Andrei Alexandrescu wrote:
 Shin Fujishiro wrote:
 Hi,

 I've had fun with the allMembers traits over the past few days and found
 it more powerful than I thought.

 __traits(allMembers, T) returns the member names of T. As some might
 already know, T is not restricted to a class or struct; it can also be
 an enum, template, or even module. Try this:
 --------------------
 enum E { a, b, c }
 template T() { int x, y, z; }
 import std.stdio;
 pragma(msg, __traits(allMembers, E).stringof);
 pragma(msg, __traits(allMembers, T).stringof);
 pragma(msg, __traits(allMembers, std.stdio).stringof);
 --------------------
 You'll like the result :). It must be usable!

 For example, using allMembers with enums, I could implement
 enumToString and enumFromString without defineEnum.
 Code: http://codepad.org/HVvPjoI7

 So, what other uses could there be?

Wow, I didn't know about this! It might as well be everything needed for a full-blown compile-time reflection package! To answer your question: for starters, try to implement BlackHole and WhiteHole as explained here: http://erdani.dreamhosters.com/cranking-policies-up.pdf

First of all, congratulations for conjuring up a cool (and marketing-savvy name) for a concept!!! Suppose I decide to use BlackHole as a base class. Would that mean that I create the base class like class RichardNixon createBlackHoleClass!() class DerivedRN : RichardNixon { /* something declared here, makes no difference in this example */ int foo(int ip) {/* whatever */} } and then, I'd expect it to work like void main() { DerivedRN drn = new DerivedRN; float ivar, jvar; jvar = drn.bar(ivar); // note: bar, not foo } and it'd work like RichardNixon were actually defined as class RichardNixon { float bar(float jv) { return float 0; } // or whatever }
May 14 2009
prev sibling next sibling parent Shin Fujishiro <rsinfu gmail.com> writes:
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 To answer your question: for starters, try to implement BlackHole and 
 WhiteHole as explained here:
 
 http://erdani.dreamhosters.com/cranking-policies-up.pdf
 

Ah, I've hand-written such BlackHoles number of times :). I thought I could implement a template which automatically generates such code, but some weird behaviors of the __traits(getVirtualFunctions) blocked me from implementing it. Anyway, I'll try to implement them again. Thanks!
May 14 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 14 May 2009 07:22:54 +0400, Shin Fujishiro <rsinfu gmail.com> wrote:

 Hi,

 I've had fun with the allMembers traits over the past few days and found
 it more powerful than I thought.

 __traits(allMembers, T) returns the member names of T. As some might
 already know, T is not restricted to a class or struct; it can also be
 an enum, template, or even module. Try this:
 --------------------
 enum E { a, b, c }
 template T() { int x, y, z; }
 import std.stdio;
 pragma(msg, __traits(allMembers, E).stringof);
 pragma(msg, __traits(allMembers, T).stringof);
 pragma(msg, __traits(allMembers, std.stdio).stringof);
 --------------------
 You'll like the result :). It must be usable!

 For example, using allMembers with enums, I could implement
 enumToString and enumFromString without defineEnum.
 Code: http://codepad.org/HVvPjoI7

 So, what other uses could there be?

Great, now the following is possible with your code: string toString(Enum)(Enum e) if (is(Enum == enum)) { return enumToString(e); } assert("RED" == toString(c)); // and, once implemented: assert("RED" == c.toString()); Although returning "Color.RED" might be better, but it's really not a problem. Is there any way your code could be contributed to Phobos?
May 14 2009
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 14 May 2009 19:24:23 +0400, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

 Shin Fujishiro wrote:
 Hi,
  I've had fun with the allMembers traits over the past few days and  
 found
 it more powerful than I thought.
  __traits(allMembers, T) returns the member names of T. As some might
 already know, T is not restricted to a class or struct; it can also be
 an enum, template, or even module. Try this:
 --------------------
 enum E { a, b, c }
 template T() { int x, y, z; }
 import std.stdio;
 pragma(msg, __traits(allMembers, E).stringof);
 pragma(msg, __traits(allMembers, T).stringof);
 pragma(msg, __traits(allMembers, std.stdio).stringof);
 --------------------
 You'll like the result :). It must be usable!
  For example, using allMembers with enums, I could implement
 enumToString and enumFromString without defineEnum.
 Code: http://codepad.org/HVvPjoI7
  So, what other uses could there be?

Wow, I didn't know about this! It might as well be everything needed for a full-blown compile-time reflection package! To answer your question: for starters, try to implement BlackHole and WhiteHole as explained here: http://erdani.dreamhosters.com/cranking-policies-up.pdf Andrei

I wonder why it says "No popular compiled language offers both" about CT introspection and code generation?
May 14 2009
prev sibling next sibling parent Shin Fujishiro <rsinfu gmail.com> writes:
Another example of allMembers: Generalized selective import.
--------------------
template isUnaryRealFunction(alias sym)
{
    enum isUnaryRealFunction = is(typeof(sym(0.L)) == real);
}

// import unary real functions from std.math
mixin importOnly!("std.math", isUnaryRealFunction);

// unary real functions are imported
static assert(__traits(compiles, abs, sqrt, sin));

// pow is not since it's a binary function
static assert(!__traits(compiles, pow));
--------------------
Full code: http://codepad.org/lc57IKIz

A template importOnly imports only symbols satisfying a predicate
template. I don't know if it's actually useful or not, but it shows the
potential of D's compile-time reflection. Seems we can do everything!
May 14 2009
prev sibling parent Shin Fujishiro <rsinfu gmail.com> writes:
"Denis Koroskin" <2korden gmail.com> wrote:
 Great, now the following is possible with your code:
 
 string toString(Enum)(Enum e) if (is(Enum == enum))
 {
     return enumToString(e);
 }
 
 assert("RED" == toString(c));
 
 // and, once implemented:
 assert("RED" == c.toString());
 
 Although returning "Color.RED" might be better, but it's really not a problem.
 Is there any way your code could be contributed to Phobos?

Sure. I think it can be merged into std.conv.to.
May 14 2009