www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Stop TypeTuple as template parameter from expanding

reply Tobias Pankrath <tobias pankrath.net> writes:
Hi,

this is an example
-----------------------------------------
template Test(S, T...)
{
    pragma(msg, "S: " ~ S.stringof);
    pragma(msg, "T: " ~ T.stringof);
}
alias TypeTuple!(A, B, C) MyList;
struct A {};
struct B {};
struct C {};


void main()
{
    Test!(MyList, A, B, C);
}
--------------------------------------------

If I compile this with dmd, it will print:
--------------------------------------------
S: A
T: (B, C, A, B, C)
test.d(153): Error: Test!(A,B,C,A,B,C) has no effect
--------------------------------------------

I don't want MyList to expand to the variadic template arguments. Instead
I want to provide Test with to different typelists. So it should print

--------------------------------------------
S: (A, B, C)
T: (A, B, C)
--------------------------------------------

How would you do this? Do I need an extra template TypeList?

Thank you

-- 
Tobias
Nov 04 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Tobias Pankrath:

 How would you do this? Do I need an extra template TypeList?

It's the design of typetuples, they are auto-flattening. I have never appreciated this design. Maybe Walter likes them this way, or they can't be designed in another way, I don't know. Bye, bearophile
Nov 04 2011
next sibling parent travert phare.normalesup.org (Christophe) writes:
bearophile , dans le message (digitalmars.D.learn:30429), a écrit :
 Tobias Pankrath:
 
 How would you do this? Do I need an extra template TypeList?

It's the design of typetuples, they are auto-flattening. I have never appreciated this design. Maybe Walter likes them this way, or they can't be designed in another way, I don't know.

You could always make them non-flattening by default, and create an operator to flatten them.
Nov 04 2011
prev sibling next sibling parent Tobias Pankrath <tobias pankrath.net> writes:
bearophile wrote:

 It's the design of typetuples, they are auto-flattening. I have never
 appreciated this design. Maybe Walter likes them this way, or they can't
 be designed in another way, I don't know.

I do like it, just it would be nice to have an alternative in phobos, iff there is no other way I am not aware of.
Nov 04 2011
prev sibling parent reply Dejan Lekic <dejan.lekic gmail.com> writes:
bearophile wrote:

 Tobias Pankrath:
 
 How would you do this? Do I need an extra template TypeList?

It's the design of typetuples, they are auto-flattening. I have never appreciated this design. Maybe Walter likes them this way, or they can't be designed in another way, I don't know. Bye, bearophile

bearophile - I believe it is a matter of taste. I actually prefer it the D way because (S, T...) is a TypeTuple as well. (MyList, A, B, C) expands to (A, B, C, A, B, C) so it makes sense that Test prints what it prints. It is all natural to me... It should be like that in my humble opinion. Perhaps the documentation should be more clear about this.
Nov 04 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Tobias Pankrath:

I do like it, just it would be nice to have an alternative in phobos, iff there
is no other way I am not aware of.<

"Type tuples" (that are allowed to contain more than just types) aren't Phobos constructs, they are built-in in the language. ---------------------- Christophe:
 You could always make them non-flattening by default, and create an
 operator to flatten them.

Yeah, but Type tuples are tricky built-in things, with a semantics quite constrained, so I don't know if this is possible. ---------------------- Dejan Lekic:
 bearophile - I believe it is a matter of taste.

When you design a language most decisions are based on "taste", because there are very few scientific studies on this topic (despite the importance of this field). A computer language is an interface between a specific implementation of not-tar-pit Turing machine and a partially sentient ape with a brain full of evolutionary design bugs. The design of programming languages touches low-determinism topics like ergonomy, usability, cognitive psycology, primate instincts, human cognitive skills and capabilities, human senses limits and capabilities, human mind design bugs, etc. So probably designing computer languages can't fully become a field of engineering. On the other hand trained taste is not arbitrary, and there are negative examples from past languages to learn from. On the third hand, most of the ideas I show in the D newsgroups turn up being wrong :-)
 I actually prefer it the D way because (S, T...) is a TypeTuple as well.
 (MyList, A, B, C) expands to (A, B, C, A, B, C) so it makes sense that Test
 prints what it prints. It is all natural to me... It should be like that in
 my humble opinion.

One of the most hated feature of Perl language is the Auto-flattening of its arrays: http://en.wikibooks.org/wiki/Perl_Programming/Array_Variables#Array_Assignment This anti-feature makes it harder to create nest arrays and in general to create nested structures (that are so natural to do in Python. There are ways to nest arrays in Perl too). As Christophe notes, it's much simpler to have Python-like lists that nest and then write and use a short recursuive flatten function in the (uncommon) cases it's needed, than trying (and failing) to invent ways to produce some nesting when your data structure auto-flattens :-( If TypeTuples nest, this too keeps being one TypeTuple: TypeTupleX!(TypeTupleX!(A, B, C), A, B, C) Bye, bearophile
Nov 05 2011
next sibling parent Tobias Pankrath <tobias pankrath.net> writes:
bearophile wrote:

 "Type tuples" (that are allowed to contain more than just types) aren't
 Phobos constructs, they are built-in in the language.

Haven't tried any of the proposed solutions yet, but they seem all very easy. If the solution were not that simple, std.typetuple could be augmented with an easy to use one. That's what I've tried to say.
Nov 05 2011
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/05/2011 03:23 PM, bearophile wrote:
 Tobias Pankrath:

 I do like it, just it would be nice to have an alternative in phobos, iff
there is no other way I am not aware of.<

"Type tuples" (that are allowed to contain more than just types) aren't Phobos constructs, they are built-in in the language. ---------------------- Christophe:
 You could always make them non-flattening by default, and create an
 operator to flatten them.

Yeah, but Type tuples are tricky built-in things, with a semantics quite constrained, so I don't know if this is possible. ---------------------- Dejan Lekic:
 bearophile - I believe it is a matter of taste.

When you design a language most decisions are based on "taste", because there are very few scientific studies on this topic (despite the importance of this field). A computer language is an interface between a specific implementation of not-tar-pit Turing machine and a partially sentient ape with a brain full of evolutionary design bugs. The design of programming languages touches low-determinism topics like ergonomy, usability, cognitive psycology, primate instincts, human cognitive skills and capabilities, human senses limits and capabilities, human mind design bugs, etc. So probably designing computer languages can't fully become a field of engineering. On the other hand trained taste is not arbitrary, and there are negative examples from past languages to learn from. On the third hand, most of the ideas I show in the D newsgroups turn up being wrong :-)
 I actually prefer it the D way because (S, T...) is a TypeTuple as well.
 (MyList, A, B, C) expands to (A, B, C, A, B, C) so it makes sense that Test
 prints what it prints. It is all natural to me... It should be like that in
 my humble opinion.

One of the most hated feature of Perl language is the Auto-flattening of its arrays: http://en.wikibooks.org/wiki/Perl_Programming/Array_Variables#Array_Assignment This anti-feature makes it harder to create nest arrays and in general to create nested structures (that are so natural to do in Python. There are ways to nest arrays in Perl too). As Christophe notes, it's much simpler to have Python-like lists that nest and then write and use a short recursuive flatten function in the (uncommon) cases it's needed, than trying (and failing) to invent ways to produce some nesting when your data structure auto-flattens :-( If TypeTuples nest, this too keeps being one TypeTuple: TypeTupleX!(TypeTupleX!(A, B, C), A, B, C) Bye, bearophile

It is _easy_ to put a TypeTuple into a nesting box. (but I have never needed to.) Usually you don't want the TypeTuples to nest, so why should that be the default?
Nov 07 2011
prev sibling next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
I just use a templated struct.

struct GroupedTypes(T...)
{
    alias T Types;
}

Then, if you need to something special with groups, you can create an 
override:

//overriding previous Test template...
template Test(T: GroupedTypes!(S), S...)
{
   
}

Tobias Pankrath wrote:

 Hi,
 
 this is an example
 -----------------------------------------
 template Test(S, T...)
 {
     pragma(msg, "S: " ~ S.stringof);
     pragma(msg, "T: " ~ T.stringof);
 }
 alias TypeTuple!(A, B, C) MyList;
 struct A {};
 struct B {};
 struct C {};
 
 
 void main()
 {
     Test!(MyList, A, B, C);
 }
 --------------------------------------------
 
 If I compile this with dmd, it will print:
 --------------------------------------------
 S: A
 T: (B, C, A, B, C)
 test.d(153): Error: Test!(A,B,C,A,B,C) has no effect
 --------------------------------------------
 
 I don't want MyList to expand to the variadic template arguments. Instead
 I want to provide Test with to different typelists. So it should print
 
 --------------------------------------------
 S: (A, B, C)
 T: (A, B, C)
 --------------------------------------------
 
 How would you do this? Do I need an extra template TypeList?
 
 Thank you
 

Nov 04 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 11/04/2011 05:28 PM, Justin Whear wrote:
 I just use a templated struct.

 struct GroupedTypes(T...)
 {
      alias T Types;
 }

 Then, if you need to something special with groups, you can create an
 override:

 //overriding previous Test template...
 template Test(T: GroupedTypes!(S), S...)
 {

 }

You don't need a struct. template GroupedTypes(T){ alias T Types; }
Nov 04 2011
prev sibling parent Tobias Brandt <tob.brandt googlemail.com> writes:
I know of two options, both not ideal:

1)

First of all, you need to declare S as an alias.
A TypeTuple is a template, not a type.

template Test(alias S, T...)
{
=A0 =A0pragma(msg, "S: " ~ S.stringof);
=A0 =A0pragma(msg, "T: " ~ T.stringof);
}

Then you can pack the type list manually into a
template, like so:

template Pack(T...)
{
    alias T unpack;
}

void main()
{
=A0 =A0Test!(Pack!(A,B,C), A, B, C);
}


This prints:

S: Pack!(A, B, C)
T: (A, B, C)



2)

The other alternative would be a nested template:

template Test(S...)
{
    template and(T...)
    {
        pragma(msg, "S: " ~ S.stringof);
=A0 =A0     pragma(msg, "T: " ~ T.stringof);
    }
}
void main()
{
=A0 =A0Test!MyList.and!(A, B, C);
}


This prints:

S: (A, B, C)
T: (A, B, C)




On 4 November 2011 11:02, Tobias Pankrath <tobias pankrath.net> wrote:
 Hi,

 this is an example
 -----------------------------------------
 template Test(S, T...)
 {
 =A0 =A0pragma(msg, "S: " ~ S.stringof);
 =A0 =A0pragma(msg, "T: " ~ T.stringof);
 }
 alias TypeTuple!(A, B, C) MyList;
 struct A {};
 struct B {};
 struct C {};


 void main()
 {
 =A0 =A0Test!(MyList, A, B, C);
 }
 --------------------------------------------

 If I compile this with dmd, it will print:
 --------------------------------------------
 S: A
 T: (B, C, A, B, C)
 test.d(153): Error: Test!(A,B,C,A,B,C) has no effect
 --------------------------------------------

 I don't want MyList to expand to the variadic template arguments. Instead
 I want to provide Test with to different typelists. So it should print

 --------------------------------------------
 S: (A, B, C)
 T: (A, B, C)
 --------------------------------------------

 How would you do this? Do I need an extra template TypeList?

 Thank you

 --
 Tobias

Nov 04 2011