July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Monday, 29 July 2013 at 17:28:57 UTC, Meta wrote:
> On Monday, 29 July 2013 at 17:22:50 UTC, JS wrote:
>> I'm not sure how named parameters would solve the original problem
>
> Your original use case:
>
> template t(T1..., T2...)
>
> ...
>
> t!(a, b, c; d, e, f);
>
> Becomes
>
> //Some weird hypothetical syntax
> template t(@name("T1") T1..., @name("T2") T2...)
> {
> ...
> }
>
> t!(T1 = a, b, c, T2 = d, e, f);
>
>> but using a syntax like what I'm suggesting one can do stuff like
>>
>> ...
>
> I think these use cases would all work with named parameters.
I don't think that is very robust notation but if it is then it would work.
Using ';' makes it obvious the next group is starting. In your notation, it seems like there could be issues. What if T2 is a local variable, then is that an assignment? If there is no possible issues then I wouldn't mind having such a syntax... anything is better than nothing.
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Monday, 29 July 2013 at 17:35:09 UTC, JS wrote: > I don't think that is very robust notation but if it is then it would work. > > Using ';' makes it obvious the next group is starting. I think using f(..., name = ...) is pretty obvious, and possibly easier to spot in a list of commas than `;`. > In your notation, it seems like there could be issues. What if T2 is a local variable, then is that an assignment? If there is no possible issues then I wouldn't mind having such a syntax... anything is better than nothing. I don't think it would be an issue, as it would work the same way as local variables in functions that shadow those in an outer scope. import std.stdio; void main() { int x = 2; int test1(int x, int y) { return x + y; } auto n = test1(0, 1); //Prints 1 writeln(n); } As for templates, I think you currently can't define templates inside a function, so that wouldn't be an issue. As for using this notation in a template argument list, I believe it works the same way for templates. alias T1 = int; template t(T1) { alias t = T1; } void main() { //Prints "string" pragma(msg, t!string); } So the requisite variadic template: alias T1 = TypeTuple!(int, string); template t(@name("T1") T1..., @name("T2") T2...) { alias t = T1; } void main() { //Should print (double, char) pragma(msg, t!(T1 = double, char, T2 = bool)); //Should print (int, string) pragma(msg, T1); } |
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Monday, 29 July 2013 at 17:52:41 UTC, Meta wrote:
>> In your notation, it seems like there could be issues. What if T2 is a local variable, then is that an assignment? If there is no possible issues then I wouldn't mind having such a syntax... anything is better than nothing.
>
> I don't think it would be an issue, as it would work the same way as local variables in functions that shadow those in an outer scope.
>
> ...
Actually, I think I misunderstood your meaning. You're right, this could be a problem. Currently:
import std.stdio;
void main()
{
int x = 0;
int test(int x, int y)
{
return x + y;
}
//Prints 2
writeln(test(x = 1, 1));
//Prints 1
writeln(x);
}
So in a hypothetical situation where we now have named parameters:
import std.stdio;
void main()
{
int x = 0;
int test(@name("x") x, @name("y") y)
{
return x + y;
}
//Prints 3
writeln(test(x = 1, y = 2));
//What does this print?
writeln(x);
}
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 07/29/13 17:03, bearophile wrote: > errors += global.endGagging(oldGaggedErrors); > > It's replaced with: > if (global.endGagging(oldGaggedErrors)) > errors = true; > > Looking at that code it's easy to think about code like this, that is not currently supported: > > errors ||= global.endGagging(oldGaggedErrors); > > Is the "||=" operator useful? Not really. errors |=!! global.endGagging(oldGaggedErrors); artur |
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 07/29/13 17:24, bearophile wrote:
> Maybe there is a way to allow that too:
>
>
> template Select(bool condition, T...) if (T.length == 2) {
> static if (condition)
> enum Select = T[0];
> else
> enum Select = T[1];
> }
>
> void main() {
> enum x = Select!(true, 10, 20);// error
> static assert(x == 10);
> int a = 1;
> int b = 2;
> alias y = Select!(true, a, b);
> assert(y == 1);
> alias T = Select!(true, int, long);
> static assert(is(T == int));
> }
>
>
> How do you tell apart values from not values? :-)
template Select(bool condition, T...) if (T.length == 2) {
static if (__traits(compiles, function { alias _1 = T[0]; alias _2 = T[1]; }))
alias Select = T[!condition];
else
enum Select = T[!condition];
}
artur
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
On 07/29/13 22:43, Artur Skawina wrote:
> On 07/29/13 17:24, bearophile wrote:
>> Maybe there is a way to allow that too:
>>
>>
>> template Select(bool condition, T...) if (T.length == 2) {
>> static if (condition)
>> enum Select = T[0];
>> else
>> enum Select = T[1];
>> }
>>
>> void main() {
>> enum x = Select!(true, 10, 20);// error
>> static assert(x == 10);
>> int a = 1;
>> int b = 2;
>> alias y = Select!(true, a, b);
>> assert(y == 1);
>> alias T = Select!(true, int, long);
>> static assert(is(T == int));
>> }
>>
>>
>> How do you tell apart values from not values? :-)
>
> template Select(bool condition, T...) if (T.length == 2) {
> static if (__traits(compiles, function { alias _1 = T[0]; alias _2 = T[1]; }))
> alias Select = T[!condition];
> else
> enum Select = T[!condition];
> }
Or even:
template Select(bool condition, T...) if (T.length == 2) {
static if (__traits(compiles, function { alias _ = T[!condition]; }))
alias Select = T[!condition];
else
enum Select = T[!condition];
}
but that's a bit /too much/ magic -- allowing
alias y1 = Select!(true, b, int);
assert(y1 == 2);
alias y2 = Select!(false, b, int);
assert(is(y2==int));
is "neat", but could be confusing...
artur
|
July 30, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert Clipsham | On Monday, 29 July 2013 at 15:02:13 UTC, Robert Clipsham wrote: > On Monday, 29 July 2013 at 14:46:02 UTC, Robert Clipsham wrote: >> You can achieve this like so: >> ---- >> template Outer(T...) { >> template Inner(U...) { >> // Do something with T and U >> } >> } >> Outer!(a, b, c).Inner!(d, e, f); >> ---- >> >> You can see an example of it in action here (type tuple intersection): >> https://github.com/mrmonday/misc/blob/master/misc/misc.d#L5 >> >> Robert > > What would be more interesting would be to have the ability to > have variadic variadics, so you could use something like: > ---- > template Outer(T...) { > template Inner(U... ...) { > // Do something with T, U[0], U[1], U[2..$] > } > } > Outer!(a, b, c).Inner!(d, e, f).Inner!(g, h, i); // Etc > ---- > Of course that raises the question of variadic variadic variadics > and variadic variadic variadic variadics and so on, and my > proposed syntax is already silly............ I don't think so, this seems similar: It would be cool if we could nest templates to get grouping template tIF(alias cond) { template tIF(alias T...) { template tIF(alias F...) { .... } } then do tIF!(cond)!(t1,t2,t3)!(f1,..,fn) which would allow for a natural grouping of variadics. The notation may seem silly but only because it is not common. which could have a short hand notation of tIF!(cond; t1, t2, t3; f1, ..., fn); (this way, if you can't keep track of your ';'s then you can use the long form) |
July 30, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 July 2013 at 14:53:10 UTC, monarch_dodra wrote:
> A simple "Group" struct will solve the problem without a second thought:
>
> struct Group(Args...)
> {
> alias Ungroup = Args;
> }
That is actually a TypeTuple that does not auto-expand. May be even worth defining it as "alias Ungroup = TypeTuple!(Args)" to be more self-documenting at cost of some redundancy.
Also it does not need to be a struct, templates are not mandatory eponymous.
I think it is best solution for topic starter problem in terms of ROI and worth inclusion into Phobos.
|
July 30, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On 7/30/13 12:36 AM, Dicebot wrote:
> On Monday, 29 July 2013 at 14:53:10 UTC, monarch_dodra wrote:
>> A simple "Group" struct will solve the problem without a second thought:
>>
>> struct Group(Args...)
>> {
>> alias Ungroup = Args;
>> }
>
> That is actually a TypeTuple that does not auto-expand. May be even
> worth defining it as "alias Ungroup = TypeTuple!(Args)" to be more
> self-documenting at cost of some redundancy.
>
> Also it does not need to be a struct, templates are not mandatory
> eponymous.
>
> I think it is best solution for topic starter problem in terms of ROI
> and worth inclusion into Phobos.
Agreed.
Andrei
|
August 10, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | On Monday, 29 July 2013 at 13:23:23 UTC, JS wrote:
> Sometimes it's nice to be able to have groups of variadic parameters:
>
> template t(T1..., T2...)
>
> ...
>
> t!(a, b, c; d, e, f);
>
> so that a,b,c are for T1 and d,e,f are for T2.
>
> This can be done by making a symbol and breaking up a single variadic but is messy.
>
> I doubt such a feature will ever get added but who knows...
I was initially unimpressed, but after some recent work I would really like this feature. I have been using
struct Group(T...)
{
alias Ungroup = T;
}
but, useful as it is, this feels like something that should have some sugar on it.
template A(T0 ..., T1 ...)
{
// use T0 & T1
}
A!(int, long, double; Point, int)
is so much nicer than
template A(T0, T1)
if(isGroup!T0 && isGroup!T1)
{
alias t0 = T0.Ungroup;
alias t1 = T1.Ungroup;
//use t0 && t1
}
A!(Group!(int, long, double), Group!(Point, int))
|
Copyright © 1999-2021 by the D Language Foundation