digitalmars.D - alias tuples?
- Janice Caron (45/45) Oct 13 2007 We've got value tuples, and we've got type tuples. Could we also have
- Reiner Pope (45/100) Oct 14 2007 You can sort of fake it. You could write your first example as
- Jarrett Billingsley (22/67) Oct 14 2007 In fact you can do this all without tuples, at least as parameters to
- Janice Caron (8/8) Oct 14 2007 I'm a little confused at how that works.
- =?ISO-8859-1?Q?Manuel_K=F6nig?= (11/22) Oct 14 2007 looking at http://www.digitalmars.com/d/tuple.html it says:
- Jarrett Billingsley (5/8) Oct 14 2007 I think it's just a bit unclear/inconsistent. For a struct S, S.tupleof...
- Janice Caron (66/71) Oct 14 2007 You mean this...?
- Jarrett Billingsley (29/76) Oct 14 2007 Maybe you didn't know this, but tuple parameters can be any mix of types...
- Jarrett Billingsley (6/9) Oct 14 2007 To comment further on this point, it _may_ be possible with D 1.0 but I
We've got value tuples, and we've got type tuples. Could we also have alias tuples? Here's what I mean. Right now I can do: struct A { X x; Y y; Z z; mixin Serialize!(x,y,z); } A a; template Serialize(alias x,alias y,alias z) { void serialize() { x.serialize(); y.serialize(); z.serialize(); } } where the types X, Y and Z all have a serialize() function (and so on recursively for every object in need of serialization). Now it seems to me, if I wanted to make Serialize!() variadic, I'd need not a value tuple, nor a type tuple, but an "alias tuple". I'd want to be able to write something like: struct A { X x; Y y; Z z; mixin Serialize!(this.aliastupleof); /* expands to (x,y,z) */ } A a; template Serialize(alias T...) { void serialize() { foreach(a;T) a.serialize(); } } Of course this won't work right now. The template won't compile because (alias T...) has no meaning, and even if it did, structs don't have an aliastupleof property. Thoughts?
Oct 13 2007
Janice Caron wrote:We've got value tuples, and we've got type tuples. Could we also have alias tuples? Here's what I mean. Right now I can do: struct A { X x; Y y; Z z; mixin Serialize!(x,y,z); } A a; template Serialize(alias x,alias y,alias z) { void serialize() { x.serialize(); y.serialize(); z.serialize(); } } where the types X, Y and Z all have a serialize() function (and so on recursively for every object in need of serialization). Now it seems to me, if I wanted to make Serialize!() variadic, I'd need not a value tuple, nor a type tuple, but an "alias tuple". I'd want to be able to write something like: struct A { X x; Y y; Z z; mixin Serialize!(this.aliastupleof); /* expands to (x,y,z) */ } A a; template Serialize(alias T...) { void serialize() { foreach(a;T) a.serialize(); } } Of course this won't work right now. The template won't compile because (alias T...) has no meaning, and even if it did, structs don't have an aliastupleof property. Thoughts?You can sort of fake it. You could write your first example as struct A { int x = 1; int y = 2; int z = 3; void serialize() { .serialize(this.tupleof); // or .serialize(x, z); if you want } } void serialize(T...)(T t) { foreach (t2; t) typeSpecificSerialize(t2); // or t2.serialize(), but that won't work with int } void typeSpecificSerialize(T)(T t) { writefln("%s: %s", T.stringof, t); // or whatever you want } --- But you don't get the variable names this way. If you want that, you can do the following, although you lose the variadic bit: void serialize(T)(T t) { foreach (i, t2; t.tupleof) { writefln("%s: [%s]", T.tupleof[i].stringof, t2); } } struct foo { int a = 1; int b = 2; } void main() { foo f; serialize(f); } --- I hope that helps, although it's not what you asked for. ;) -- Reiner
Oct 14 2007
"Janice Caron" <caron800 googlemail.com> wrote in message news:mailman.422.1192341718.16939.digitalmars-d puremagic.com...We've got value tuples, and we've got type tuples. Could we also have alias tuples? Here's what I mean. Right now I can do: struct A { X x; Y y; Z z; mixin Serialize!(x,y,z); } A a; template Serialize(alias x,alias y,alias z) { void serialize() { x.serialize(); y.serialize(); z.serialize(); } } where the types X, Y and Z all have a serialize() function (and so on recursively for every object in need of serialization). Now it seems to me, if I wanted to make Serialize!() variadic, I'd need not a value tuple, nor a type tuple, but an "alias tuple". I'd want to be able to write something like: struct A { X x; Y y; Z z; mixin Serialize!(this.aliastupleof); /* expands to (x,y,z) */ } A a; template Serialize(alias T...) { void serialize() { foreach(a;T) a.serialize(); } } Of course this won't work right now. The template won't compile because (alias T...) has no meaning, and even if it did, structs don't have an aliastupleof property. Thoughts?In fact you can do this all without tuples, at least as parameters to templates. class X { void serialize() {} } class Y : X{} class Z : X{} struct A { X x; Y y; Z z; mixin Serialize; } template Serialize() { void serialize() { foreach(a; this.tupleof) a.serialize(); } }
Oct 14 2007
I'm a little confused at how that works. Surely, this.tupleof returns a type tuple - that is, a sequence of types? Surely then, the "a" in the foreach would be a type, not a member variable name? Surely then, a.serialize() would be calling each type's /static/ serialize() function, rather than the member function? The goal is to call a function once for each actual struct member, not once for each member's type. Am I completely misunderstanding this?
Oct 14 2007
Janice Caron wrote:I'm a little confused at how that works. Surely, this.tupleof returns a type tuple - that is, a sequence of types? Surely then, the "a" in the foreach would be a type, not a member variable name? Surely then, a.serialize() would be calling each type's /static/ serialize() function, rather than the member function? The goal is to call a function once for each actual struct member, not once for each member's type. Am I completely misunderstanding this?looking at http://www.digitalmars.com/d/tuple.html it says: "The data fields of a struct or class can be turned into an _expression_ tuple using the .tupleof property" (below that you find an example that actually uses it) I tested it myself and it works. I actually use it to implement functions in a generic matrix struct. But http://www.digitalmars.com/d/tuple.html (section Struct Properties) states: ".tupleof Gets _type_ tuple of fields" I think that's a typo and should be fixed.
Oct 14 2007
"Manuel König" <ManuelK89 gmx.net> wrote in message news:feu01n$cs1$1 digitalmars.com...Janice Caron wrote: ".tupleof Gets _type_ tuple of fields" I think that's a typo and should be fixed.I think it's just a bit unclear/inconsistent. For a struct S, S.tupleof gets a tuple of its members' types. But S s; s.tupleof gets a tuple of the instance s's members. Same goes for classes. And unions.
Oct 14 2007
On 10/14/07, Manuel König <ManuelK89 gmx.net> wrote:looking at http://www.digitalmars.com/d/tuple.html it says: "The data fields of a struct or class can be turned into an _expression_ tuple using the .tupleof property" (below that you find an example that actually uses it) I tested it myself and it works.You mean this...? OK, that's slightly more interesting. It looks like S.tupleof gets you type tuple, while s.tupleof gets you an expression tuple. But neither is what I'm looking for. I want to get _aliases_ into a tuple. This would open the door to powerful variadic metaprogramming, just as (non-variadic) alias template parameters do for (non-variadic) templates. Going back to structs, for example, member variable names are features of S (the structure declaration), not of s (an instance of S), so if we wanted to automate their extraction, you'd need a new property for struct types. But that would only really be icing on the cake, because really it's the aliasing side of things where it would matter most. See, right now, I have a quite nice piece of code which looks a little bit like this (I've simplified it for illustration purposes) struct A { B b; C c; mixin SomeNiceFunctions!(b,c); } struct B { D d; E e; F f; mixin SomeNiceFunctions!(d,e,f); } struct C { F f; G g; D d; H h; mixin SomeNiceFunctions!(f,g,d,h); } Now this is all very cool and marvellous, and already /way/ better than C++, but nonetheless I still have to write several different versions of the mixin, one for each different number of parameters. Specifically: template SomeNiceFunctions!(alias a,alias b) { /*...*/ } template SomeNiceFunctions!(alias a,alias b,alias c) { /*...*/ } template SomeNiceFunctions!(alias a,alias b,alias c,alias d) { /*...*/ } How much nicer it would be to instead be able to do: template SomeNiceFunctions!(alias a...) { /*...*/ } and then use a foreach (static foreach?) within the definition to dereference each alias in turn. That's really what I'm getting at. (Being able to automate the parameter list at the mixin site would be a nice added bonus, but not essential).
Oct 14 2007
"Janice Caron" <caron800 googlemail.com> wrote in message news:mailman.442.1192397473.16939.digitalmars-d puremagic.com...OK, that's slightly more interesting. It looks like S.tupleof gets you type tuple, while s.tupleof gets you an expression tuple. But neither is what I'm looking for. I want to get _aliases_ into a tuple. This would open the door to powerful variadic metaprogramming, just as (non-variadic) alias template parameters do for (non-variadic) templates. Going back to structs, for example, member variable names are features of S (the structure declaration), not of s (an instance of S), so if we wanted to automate their extraction, you'd need a new property for struct types. But that would only really be icing on the cake, because really it's the aliasing side of things where it would matter most. See, right now, I have a quite nice piece of code which looks a little bit like this (I've simplified it for illustration purposes) struct A { B b; C c; mixin SomeNiceFunctions!(b,c); } struct B { D d; E e; F f; mixin SomeNiceFunctions!(d,e,f); } struct C { F f; G g; D d; H h; mixin SomeNiceFunctions!(f,g,d,h); } Now this is all very cool and marvellous, and already /way/ better than C++, but nonetheless I still have to write several different versions of the mixin, one for each different number of parameters. Specifically: template SomeNiceFunctions!(alias a,alias b) { /*...*/ } template SomeNiceFunctions!(alias a,alias b,alias c) { /*...*/ } template SomeNiceFunctions!(alias a,alias b,alias c,alias d) { /*...*/ } How much nicer it would be to instead be able to do: template SomeNiceFunctions!(alias a...) { /*...*/ } and then use a foreach (static foreach?) within the definition to dereference each alias in turn. That's really what I'm getting at. (Being able to automate the parameter list at the mixin site would be a nice added bonus, but not essential).Maybe you didn't know this, but tuple parameters can be any mix of types, expressions, and aliases. This is already entirely possible. class X { void serialize() {} }; class Y : X{} class Z : X{} struct A { X x; Y y; Z z; mixin SomeNiceFunctions!(x, y, z); } template SomeNiceFunctions(T...) { static if(T.length > 0) { mixin(typeof(T[0]).stringof ~ " get" ~ T[0].stringof ~ "() { return " ~ T[0].stringof ~ "; }"); static if(T.length > 1) mixin SomeNiceFunctions!(T[1 .. $]); } } void main() { A a; Stdout.formatln("{}", a.getx() is null); }
Oct 14 2007
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:feumc4$1qi7>>To comment further on this point, it _may_ be possible with D 1.0 but I can't manage to mangle the code enough to get the compiler to accept it. I think this would be much easier with D 2.0's compile-time reflection capabilities.(Being able to automate the parameter list at the mixin site would be a nice added bonus, but not essential).
Oct 14 2007