July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | John Colvin: > There are a mind-boggling large number of things that are useful, but that's not the criteria for adding something to a programming language. > > A new feature has to be *sufficiently* useful to justify the increased complexity of the language and it's implementations (plus not clashing badly with other features). Example use cases are a useful way of demonstrating just how useful a feature can be. As example take a look at this commit, a small part of the changes to port the D front-end to D: https://github.com/D-Programming-Language/dmd/compare/428e559e5f0b...68ab05dba14a In this original line 'errors' is a boolean: 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? Is it working well with the rest of the language? Is it easy to understand a read? It is not bug-prone given the existence of the "|=" operator? Even if all those answers are positive, you have to ask yourself if it's also sufficiently useful... Bye, bearophile |
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | monarch_dodra: > Select!(cond, 1, 2);// This doesn't compile Time ago I asked for an improvement of Select: https://github.com/D-Programming-Language/phobos/pull/1235 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? :-) Bye, bearophile |
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > How do you tell apart values from not values? :-)
Is this brutal enough? :-)
enum SameKind(T...) =
__traits(compiles, {enum x = T[0], y = T[1]; }) ||
__traits(compiles, {alias x = T[0]; alias y = T[1]; });
template Select(bool condition, T...)
if (T.length == 2 && SameKind!T) {
static if (__traits(compiles, {enum x = T[0];})) {
static if (condition)
enum Select = T[0];
else
enum Select = T[1];
} else {
static if (condition)
alias Select = T[0];
else
alias Select = T[1];
}
}
void main() {
enum x = Select!(true, 10, 20);
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));
}
Bye,
bearophile
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > template Select(bool condition, T...)
> if (T.length == 2 && SameKind!T) {
> static if (__traits(compiles, {enum x = T[0];})) {
> static if (condition)
> enum Select = T[0];
> else
> enum Select = T[1];
> } else {
> static if (condition)
> alias Select = T[0];
> else
> alias Select = T[1];
> }
> }
It works in simple cases and maybe it's worth changing in some way the Select of Phobos, to support values too.
But to solve the problem in general I think there's a need for "lazy template arguments", similar to lazy function arguments, but for types.
template Select(condition, lazy T1, lazy T2) {...}
Bye,
bearophile
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Monday, 29 July 2013 at 15:31:39 UTC, bearophile wrote:
>> How do you tell apart values from not values? :-)
>
> Is this brutal enough? :-)
>
>
> enum SameKind(T...) =
> __traits(compiles, {enum x = T[0], y = T[1]; }) ||
> __traits(compiles, {alias x = T[0]; alias y = T[1]; });
>
> template Select(bool condition, T...)
> if (T.length == 2 && SameKind!T) {
> static if (__traits(compiles, {enum x = T[0];})) {
> static if (condition)
> enum Select = T[0];
> else
> enum Select = T[1];
> } else {
> static if (condition)
> alias Select = T[0];
> else
> alias Select = T[1];
> }
> }
>
> void main() {
> enum x = Select!(true, 10, 20);
> 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));
> }
>
> Bye,
> bearophile
But it's still "Select!(true, a, b)" and not "Select!(true, 1, 2)"...
Simple overloads could help here?
template Select(bool condition, T1, T2)
{
static if (condition) alias Select = T1;
else alias Select = T2;
}
template Select(bool condition, alias T1, alias T2)
{
static if (condition) alias Select = T1;
else alias Select = T2;
}
template Select(bool condition, alias T1, T2)
{
static if (condition) alias Select = T1;
else alias Select = T2;
}
template Select(bool condition, T1, alias T2)
{
static if (condition) alias Select = T1;
else alias Select = T2;
}
*Now* Select!(condition, 1, 2) works.
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 July 2013 at 15:57:36 UTC, monarch_dodra wrote:
> On Monday, 29 July 2013 at 15:31:39 UTC, bearophile wrote:
>>> How do you tell apart values from not values? :-)
>>
>> Is this brutal enough? :-)
>>
>>
>> enum SameKind(T...) =
>> __traits(compiles, {enum x = T[0], y = T[1]; }) ||
>> __traits(compiles, {alias x = T[0]; alias y = T[1]; });
>>
>> template Select(bool condition, T...)
>> if (T.length == 2 && SameKind!T) {
>> static if (__traits(compiles, {enum x = T[0];})) {
>> static if (condition)
>> enum Select = T[0];
>> else
>> enum Select = T[1];
>> } else {
>> static if (condition)
>> alias Select = T[0];
>> else
>> alias Select = T[1];
>> }
>> }
>>
>> void main() {
>> enum x = Select!(true, 10, 20);
>> 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));
>> }
>>
>> Bye,
>> bearophile
>
> But it's still "Select!(true, a, b)" and not "Select!(true, 1, 2)"...
Wait never mind my above post. Your approach works.
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 July 2013 at 16:00:47 UTC, monarch_dodra wrote:
>
> Wait never mind my above post. Your approach works.
Except for this...
alias K = Select!(true, 4, int);
;)
Useful? I don't think so... but I thought I'd point it out ^^
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Monday, 29 July 2013 at 16:02:02 UTC, monarch_dodra wrote:
> Except for this...
> alias K = Select!(true, 4, int);
>
> ;)
>
> Useful? I don't think so... but I thought I'd point it out ^^
I think it's a feature that this doesn't work. As for variadic grouping, named parameters could easily solve this problem, and have applications for other situations beside variadic arguments.
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Monday, 29 July 2013 at 16:52:17 UTC, Meta wrote:
> On Monday, 29 July 2013 at 16:02:02 UTC, monarch_dodra wrote:
>> Except for this...
>> alias K = Select!(true, 4, int);
>>
>> ;)
>>
>> Useful? I don't think so... but I thought I'd point it out ^^
>
> I think it's a feature that this doesn't work. As for variadic grouping, named parameters could easily solve this problem, and have applications for other situations beside variadic arguments.
I'm not sure how named parameters would solve the original problem but using a syntax like what I'm suggesting one can do stuff like
template Log(alias cond, args...; string file = __FILE__, string mod = __MODULE__)
{
}
which could be called without explicitly having to supply __FILE__ and __MODULE__, currently you can't write such a CT logging feature with variadic parameters.
(although another solution would to have __PREVIOUS_FILE__, __PREVIOUS_MODULE__, etc... that would return the file, module, line number, etc.. of what called the template or function)
I think using the ';' notation is very concise and natural... just that forgetting to use it could be very problematic.
|
July 29, 2013 Re: Variadic grouping | ||||
---|---|---|---|---|
| ||||
Posted in reply to JS | 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. |
Copyright © 1999-2021 by the D Language Foundation