Thread overview
tuples and names
Nov 16, 2006
Kevin Bealer
Nov 16, 2006
Kevin Bealer
Nov 17, 2006
Don Clugston
November 16, 2006
I wonder if it's possible to get the names of fields of a struct?  What I'm imagining is this kind of usage:

struct Foo {
   int x;
   char[] y;
};

template(T) {
  void PrintAsXml(T z)
  {
      char[] name = z.fieldnamesof;

      alias ParameterTypeTuple!(T) TP;

      foreach(auto A; z.tupleof) {
          writefln("<%s>%s</%s>", name, A, name);
      }
  }
}

Which might print (assuming z.x = 5 and z.y = "hello"):
<x>5</x>
<y>hello</y>

This might also be a way to look for a function by a given name, as with Java's reflective capability, althought I would imagine data field names would be a seperate operator than method names.

Kevin
November 16, 2006
Sorry - that should be:
      foreach(int i, auto A; z.tupleof) {
          writefln("<%s>%s</%s>", name[i], A, name[i]);
      }

I'm thinking that .fieldnamesof would return a tuple of char[] objects, and maybe there would be a .methodnames of that returns method names (or signatures?) to allow searching by name for delegate binding purposes.

One application of this is serialization.  Another might be something like the "xpath" functionality of Java's XML support, i.e. I could have a complex series of nested structures and do something like this:

struct Foo {
...
  Bar b;
}

struct Bar {
...
  Car c;
}

struct Car {
...
  int d;
}

char[] name = "Foo.b.c.d";
int * d_found;
Foo document;

// Set d_found to a pointer into Foo.b.c.d:
FindStructPath!(document, name, d_found);

If we had the field names, this kind of FindStructPath!() template could be written.

For a program like a web browser, being able to specify paths into document objects or similar could lead to powerful configurability.

I also wanted to say that I've been away for a bit but the rate of progress here is still really amazing.  The rise in TIOBE rank (almost every language with a higher rank is a household name), version 1.0 in January already, and the language features and library innovations still keep pouring in!

Kevin
November 17, 2006
Kevin Bealer wrote:
> Sorry - that should be:
>       foreach(int i, auto A; z.tupleof) {
>           writefln("<%s>%s</%s>", name[i], A, name[i]);
>       }
> 
> I'm thinking that .fieldnamesof would return a tuple of char[] objects, and maybe
> there would be a .methodnames of that returns method names (or signatures?) to
> allow searching by name for delegate binding purposes.

I was trying to do exactly this, with the applications you mention. I already have a module meta.NameOf, which given any alias, returns the name.

eg. this works:
----------
module mymodule;
import meta.NameOf;

struct S { int x; int y; }

void main()
{
   int [] x;
   S s;
   static assert(symbolnameof!(x) == "x");
   static assert(prettynameof!(x) == "int [] mymodule.main.x");
   static assert(prettynameof!(s) ==
           "struct mymodule.S mymodule.main.s");
}
----------
Unfortunately, .tupleof can't return aliases, and although alias tuples exist, you can't index or slice them.
If S.tupleof returned aliases of each of its members,
and if it was legal to index an alias tuple, we'd be done.

IE, we already have:

s.tupleof --> returns an expression tuple
typeof(s.tupleof) --> returns a type tuple
typeof(S.tupleof) --> returns a type tuple

and we'd have:

S.tupleof --> returns an alias tuple (currently doesn't compile)
typeof(s).tupleof --> returns an alias tuple (currently doesn't compile)
typeof(typeof(s).tupleof) --> returns a type tuple (currently doesn't compile)

and
symbolnameof!(S.tupleof[0]) == "x"

Now arguably we'd be better off with built-in .nameof properties for any alias, rather than my library function, but the concept is unchanged.

Oh, and add another property
.methodtupleof
for all the member functions, which behaves exactly the same as .tupleof, allow both of them to apply to modules as well as structs and classes -- and then compile-time reflection becomes quite comprehensive.