digitalmars.D.learn - Why can't templates use tuples for for argument types?
- BCS (8/8) Jul 16 2007 |template Types(A...)
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (8/24) Jul 16 2007 Probably because the compiler does not unfold the tuple. I've filed a bu...
- BCS (3/11) Jul 16 2007 So you are saying it's a bug?
- Jari-Matti =?ISO-8859-1?Q?M=E4kel=E4?= (12/26) Jul 16 2007 I think the first class tuples -bug covers this too:
- BCS (3/8) Jul 17 2007
- Don Clugston (4/12) Jul 17 2007 int [] is not an allowed as a template value parameter. Only char[], wch...
- BCS (23/27) Jul 17 2007 strange, this works
- Jarrett Billingsley (8/18) Jul 17 2007 template Foo(A...)
- BCS (8/32) Jul 17 2007 How did you hack my system!!!! I'm sure you copied that right off my har...
- Jarrett Billingsley (17/24) Jul 17 2007 The issue is that there's currently no way to specify that a template
- BCS (5/38) Jul 17 2007 I like the ".." my thought was allow tuples anywhere, but if they aren't...
- Bill Baxter (5/38) Jul 17 2007 Walter resoundingly rejected some other proposal that involved '..' on
- BCS (8/51) Jul 18 2007 How about
- Bill Baxter (15/55) Jul 18 2007 Rather than proposing a bunch of new syntax, isn't the solution just to
- Jarrett Billingsley (5/12) Jul 18 2007 Well the issue is that an identifier as a template parameter already has...
- Bill Baxter (16/30) Jul 18 2007 Yeh I meant for the A to be a type there.
- Reiner Pope (33/71) Jul 19 2007 Actually, I only saw this thread a few days ago (because I don't read
- BCS (27/37) Jul 19 2007 One thing that it would be useful for would be a tuple template that doe...
- Bill Baxter (14/58) Jul 19 2007 Ok. So it's basically for writing functions that manipulate tuples
- BCS (2/8) Jul 19 2007 Ahh. The joys of hypothetical syntax!!
- James Dennett (7/21) Jul 17 2007 Not true of C++. Pointers to objects with external linkage
- Don Clugston (7/30) Jul 19 2007 I would classify those as alias parameters, not value parameters. It's t...
|template Types(A...) |{ | template Values(A a) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;
Jul 16 2007
BCS wrote:|template Types(A...) |{ | template Values(A a) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;Probably because the compiler does not unfold the tuple. I've filed a bug about instantiating an array literal from a tuple. It has a similar problem: alias Tuple!(1,2,3) a; int[] foo = [ a ]; // does not work, but int[] foo = [ a[0], a[1], a[2] ]; // does Here you can also do|template Types(A...) |{ | template Values(A[0] a, A[1] b, A[2] c) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;
Jul 16 2007
Reply to Jari-Matti Mäkelä,Probably because the compiler does not unfold the tuple. I've filed a bug about instantiating an array literal from a tuple. It has a similar problem: alias Tuple!(1,2,3) a; int[] foo = [ a ]; // does not work, but int[] foo = [ a[0], a[1], a[2] ]; // doesSo you are saying it's a bug? In that case, what is the bug number so I can add some more comments?
Jul 16 2007
BCS wrote:Reply to Jari-Matti Mäkelä,I think the first class tuples -bug covers this too: http://d.puremagic.com/issues/show_bug.cgi?id=1293 If you feel it's worth a new bug report, please do as you wish. I have to admit the situation is a bit unorthogonal - for example these work too: alias Tuple(int,int) a; void foo(a b) {} void bar() { a b; } But template baz(a b) {} doesn't.Probably because the compiler does not unfold the tuple. I've filed a bug about instantiating an array literal from a tuple. It has a similar problem: alias Tuple!(1,2,3) a; int[] foo = [ a ]; // does not work, but int[] foo = [ a[0], a[1], a[2] ]; // doesSo you are saying it's a bug? In that case, what is the bug number so I can add some more comments?
Jul 16 2007
Reply to Jari-Matti Mäkelä,I think the first class tuples -bug covers this too: http://d.puremagic.com/issues/show_bug.cgi?id=1293 If you feel it's worth a new bug report, please do as you wish.I just added my comments to that bug
Jul 17 2007
BCS wrote:|template Types(A...) |{ | template Values(A a) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;int [] is not an allowed as a template value parameter. Only char[], wchar[], dchar[], integers, and floating-point types can be template value parameters. (In C++, only integers are allowed).
Jul 17 2007
Reply to Don,int [] is not an allowed as a template value parameter. Only char[], wchar[], dchar[], integers, and floating-point types can be template value parameters. (In C++, only integers are allowed).strange, this works |template Types(A...) |{ | template Values(B...) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob; And while I'm thinking about it; why isn't there something like a "one space tuple"? A few times, I have wanted a template that works just like a tuple taking template but where one or more of the spots must be filled and a keep separate from the rest. template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); this shouldn't Foo!(); (alias dosen't work)
Jul 17 2007
"BCS" <ao pathlink.com> wrote in message news:ce0a3343bf108c99670e3f3ff2c news.digitalmars.com...A few times, I have wanted a template that works just like a tuple taking template but where one or more of the spots must be filled and a keep separate from the rest. template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); this shouldn't Foo!();template Foo(A...) { static assert(A.length >= 1, "Foo needs at least one parameter"); do something with A[0]; do something else with A[1 .. $]; }
Jul 17 2007
Reply to Jarrett,"BCS" <ao pathlink.com> wrote in message news:ce0a3343bf108c99670e3f3ff2c news.digitalmars.com...How did you hack my system!!!! I'm sure you copied that right off my hard drive }:-| <g> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...A few times, I have wanted a template that works just like a tuple taking template but where one or more of the spots must be filled and a keep separate from the rest. template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); this shouldn't Foo!();template Foo(A...) { static assert(A.length >= 1, "Foo needs at least one parameter"); do something with A[0]; do something else with A[1 .. $]; }
Jul 17 2007
"BCS" <ao pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a news.digitalmars.com...How did you hack my system!!!! I'm sure you copied that right off my hard drive }:-| <g> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...The issue is that there's currently no way to specify that a template parameter can be 'anything'. T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value. If you could specify that a parameter could take anything, this would be trivial. How about using .. - it means it's kind of like a tuple, but shorter ;) template Foo(A.., B...) { } Or, take a page from Erlang: template Foo(A | B...) { } In this case, A can be anything, and not just a type, because it's on the left of a bar. An issue with this, however, is that you can't have a type parameter.
Jul 17 2007
Reply to Jarrett,"BCS" <ao pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a news.digitalmars.com...I like the ".." my thought was allow tuples anywhere, but if they aren't at the end, they take one and only one thing. template Foo(A..., B...) However it seems a bit messy with the location sensitive semantics.How did you hack my system!!!! I'm sure you copied that right off my hard drive }:-| <g> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...The issue is that there's currently no way to specify that a template parameter can be 'anything'. T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value. If you could specify that a parameter could take anything, this would be trivial. How about using .. - it means it's kind of like a tuple, but shorter ;) template Foo(A.., B...) { } Or, take a page from Erlang: template Foo(A | B...) { } In this case, A can be anything, and not just a type, because it's on the left of a bar. An issue with this, however, is that you can't have a type parameter.
Jul 17 2007
Jarrett Billingsley wrote:"BCS" <ao pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a news.digitalmars.com...Walter resoundingly rejected some other proposal that involved '..' on the grounds that '..' looks far too much like '...' to bleary eyes. So I think .. is out. --bbHow did you hack my system!!!! I'm sure you copied that right off my hard drive }:-| <g> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...The issue is that there's currently no way to specify that a template parameter can be 'anything'. T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value. If you could specify that a parameter could take anything, this would be trivial. How about using .. - it means it's kind of like a tuple, but shorter ;) template Foo(A.., B...) { } Or, take a page from Erlang: template Foo(A | B...) { } In this case, A can be anything, and not just a type, because it's on the left of a bar. An issue with this, however, is that you can't have a type parameter.
Jul 17 2007
Bill Baxter wrote:Jarrett Billingsley wrote:How about A[1]... or A...[1] This would be a tuple that must have exactly 1 item. Plainly this would also allow A[4]... , a tuple with 4 items and might also extend to A[3..5]... a tuple with 3,4 or 5 items. (or would that be 3 or 4 to match the slice semantics?) This last bit wouldn't mix with normal tuples though."BCS" <ao pathlink.com> wrote in message news:ce0a3343bf268c99691d2e8b71a news.digitalmars.com...Walter resoundingly rejected some other proposal that involved '..' on the grounds that '..' looks far too much like '...' to bleary eyes. So I think .. is out. --bbHow did you hack my system!!!! I'm sure you copied that right off my hard drive }:-| <g> All joking aside, I keep running into that so often that I want a cleaner way to do it. I want the proper usage documented in the code, not the comments and the asserts. I want to be able to talk about things by name without having to make aliases. It's a minor point but...The issue is that there's currently no way to specify that a template parameter can be 'anything'. T means it's a type, alias T means it's a symbol, and <sometype> T means it's a value. If you could specify that a parameter could take anything, this would be trivial. How about using .. - it means it's kind of like a tuple, but shorter ;) template Foo(A.., B...) { } Or, take a page from Erlang: template Foo(A | B...) { } In this case, A can be anything, and not just a type, because it's on the left of a bar. An issue with this, however, is that you can't have a type parameter.
Jul 18 2007
BCS wrote:Reply to Don,Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected? If you want at least one thing it seems perfectly reasonable to me to do: template Foo(A, B...) { alias Tuple!(A,B) ArgTuple; ... } if that doesn't work, then that's what needs to be fixed. I don't really understand the point of wanting to be able to specify a template argument that could be *anything* -- alias, value, or symbol. Other than a big static if, I can't see how you would be able to implement any functionality when it could be any one of those things. But I'm probably just being dense. --bbint [] is not an allowed as a template value parameter. Only char[], wchar[], dchar[], integers, and floating-point types can be template value parameters. (In C++, only integers are allowed).strange, this works |template Types(A...) |{ | template Values(B...) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob; And while I'm thinking about it; why isn't there something like a "one space tuple"? A few times, I have wanted a template that works just like a tuple taking template but where one or more of the spots must be filled and a keep separate from the rest. template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); this shouldn't Foo!(); (alias dosen't work)
Jul 18 2007
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:f7m9k9$es4$1 digitalmars.com...Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected? If you want at least one thing it seems perfectly reasonable to me to do: template Foo(A, B...) { alias Tuple!(A,B) ArgTuple; ... }Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter. Changing it to allow anything seems awfully scary, hence the suggestions for new syntax.
Jul 18 2007
Jarrett Billingsley wrote:"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:f7m9k9$es4$1 digitalmars.com...Yeh I meant for the A to be a type there. I guess I just don't understand the use case for BCS's original example: template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); If you don't even know what kind of entity a thing is, there's not much you can do with it. Anyway, since it's been a basically a dialogue between you and BCS so far, something tells me you haven't hit a nerve with many folks. My guess is that most folks aren't clear what the motivating use case is. And probably Walter isn't going to be much interested in this either without good use case examples. --bbRather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected? If you want at least one thing it seems perfectly reasonable to me to do: template Foo(A, B...) { alias Tuple!(A,B) ArgTuple; ... }Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter. Changing it to allow anything seems awfully scary, hence the suggestions for new syntax.
Jul 18 2007
Bill Baxter wrote:Jarrett Billingsley wrote:Actually, I only saw this thread a few days ago (because I don't read d.learn as much as the main group), and I am surprised that so few people responded. To me, this is one part of a whole lot of issues with template parameters, which I hope will sometime be solved by a big reform. Otherwise, it will remain what seems today to be a collection of kludges. As far as I'm concerned, the problems are: 1. tuple parameters allow int[] (and double[] and double[][], etc) as value parameters; template value parameters don't 2. there's no equivalent to typesafe varargs: you can't say, "give me a type tuple" or "give me a tuple of aliases" or "give me a value tuple" -- you can only say "give me a tuple" and then do static asserts. I find this quite annoying because most of the time I know exactly which I want. 3. There's no easy way to specify "give me just one value parameter of any type." The closest you can get is template foo(T, T S) {...} but the instantiation requires: foo!(int, 5); 4. There's no way to specify what BCS mentioned: "give me just one parameter, of any kind". I haven't needed this yet, though. 5. You can't do proper nested tuples without a going through "compile-time structs". (when thinking about template parameters in the past, I've always found it difficult to distinguish between "type" as in int/char/etc, and the "type" of a template parameter as in value/alias/type. I think "kind" is a good word for the latter) I don't know what other people think of these problems, but they don't seem too hard to solve (mind you, I haven't worked out the details, so I could well be wrong). I would imagine setting up some sort of inheritance of template parameter kind, so that there's a base kind, "any", from which "value", "alias" and "type" inherit, and from the "value" kind, all of the regular D types also inherit. [Additionally, you solve problem 1 above by, well, solving it.]"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message news:f7m9k9$es4$1 digitalmars.com...Yeh I meant for the A to be a type there. I guess I just don't understand the use case for BCS's original example: template Foo(A, B...) {} these should work Foo!(1, int); Foo!(int, 1); Foo!(Foo!(int, 1)); If you don't even know what kind of entity a thing is, there's not much you can do with it. Anyway, since it's been a basically a dialogue between you and BCS so far, something tells me you haven't hit a nerve with many folks. My guess is that most folks aren't clear what the motivating use case is. And probably Walter isn't going to be much interested in this either without good use case examples.Rather than proposing a bunch of new syntax, isn't the solution just to make those things work as expected? If you want at least one thing it seems perfectly reasonable to me to do: template Foo(A, B...) { alias Tuple!(A,B) ArgTuple; ... }Well the issue is that an identifier as a template parameter already has a well-defined meaning - it's a type parameter. Changing it to allow anything seems awfully scary, hence the suggestions for new syntax.
Jul 19 2007
Reply to Bill,I don't really understand the point of wanting to be able to specify a template argument that could be *anything* -- alias, value, or symbol. Other than a big static if, I can't see how you would be able to implement any functionality when it could be any one of those things. But I'm probably just being dense. --bbOne thing that it would be useful for would be a tuple template that does something with any tuple type // take exactly 2 and return true if they are the same template IsSame(A..,B..){const bool IsSame = ...} // take 1 or more and remove all of the first from the rest template Remove(remove.., from...) { static if(from.length == 0) { alias from Remove; } else { staic if(IsSame!(remove, from[0])) { alias Remove!(remove,from[1..$]) Remove } else { alias T!(from[0], Remove!(remove,from[1..$])) Remove } } } this would work as: Remove!(1,4,5,6,7,1,2,3); // gives (4,5,6,7,2,3) Remove!(int, byte, short, int, long); // gives (byte, short, long)
Jul 19 2007
BCS wrote:Reply to Bill,Ok. So it's basically for writing functions that manipulate tuples themselves. I agree, it does make sense to be able to do that, in a Lisp-y completeness kind of way. You can write something like Remove!(1).from!(4,5,6,1,2,3,4) now. Then if the first tuple is empty you just don't remove anything (and you can additionally enhance it to remove any of N things from the list instead of just 1 thing). But still, tuples are the cons and cdr of template metaprogramming. There shouldn't be arbitrary restrictions on how you can manipulate them based on what's in the slots. As an aside, I think Walter's right about the dots. I misread your example as being two '..'s initially instead of one .. and one ... arg. I did just wake up though. :-) --bbI don't really understand the point of wanting to be able to specify a template argument that could be *anything* -- alias, value, or symbol. Other than a big static if, I can't see how you would be able to implement any functionality when it could be any one of those things. But I'm probably just being dense. --bbOne thing that it would be useful for would be a tuple template that does something with any tuple type // take exactly 2 and return true if they are the same template IsSame(A..,B..){const bool IsSame = ...} // take 1 or more and remove all of the first from the rest template Remove(remove.., from...) { static if(from.length == 0) { alias from Remove; } else { staic if(IsSame!(remove, from[0])) { alias Remove!(remove,from[1..$]) Remove } else { alias T!(from[0], Remove!(remove,from[1..$])) Remove } } } this would work as: Remove!(1,4,5,6,7,1,2,3); // gives (4,5,6,7,2,3) Remove!(int, byte, short, int, long); // gives (byte, short, long)
Jul 19 2007
Reply to Bill,As an aside, I think Walter's right about the dots. I misread your example as being two '..'s initially instead of one .. and one ... arg. I did just wake up though. :-) --bbAhh. The joys of hypothetical syntax!!
Jul 19 2007
Don Clugston wrote:BCS wrote:Not true of C++. Pointers to objects with external linkage are also allowed (even if we assume "integers" includes booleans and values of enumeration types). (Allowing floating point types used to be a common extension in C++ but was removed after experience with it.) -- James|template Types(A...) |{ | template Values(A a) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;int [] is not an allowed as a template value parameter. Only char[], wchar[], dchar[], integers, and floating-point types can be template value parameters. (In C++, only integers are allowed).
Jul 17 2007
James Dennett wrote:Don Clugston wrote:I would classify those as alias parameters, not value parameters. It's the name, not the value, which gets name mangled. (even if we assume "integers" includesBCS wrote:Not true of C++. Pointers to objects with external linkage are also allowed|template Types(A...) |{ | template Values(A a) | { | } |} | |alias Types!(int, bool, int[]).Values!(1,true,[1,2,3]) bob;int [] is not an allowed as a template value parameter. Only char[], wchar[], dchar[], integers, and floating-point types can be template value parameters. (In C++, only integers are allowed).booleans and values of enumeration types).Yes. IIRC, there's no distinction between them.(Allowing floating point types used to be a common extension in C++ but was removed after experience with it.)Yes, I think I saw it in an early version of Borland C++. But I don't see how you can do it properly without clearly specifying the FP ABI.-- James
Jul 19 2007