Variadic grouping

JS js.mdnq at gmail.com
Mon Jul 29 07:21:44 PDT 2013


On Monday, 29 July 2013 at 13:59:54 UTC, bearophile wrote:
> JS:
>
>> The usefulness should be obvious and I seriously doubt if 
>> someone thinks it is not then any example I could give would 
>> convince them otherwise.
>
> It's not obvious for me :-) Explaining the "obvious" is 
> sometimes necessary.
>
>
>> It came up for me trying to write a ternary if to use.
>>
>>
>> struct tVariadicSplit { }
>> template tuple(args...) { alias tuple = args; }
>> template tMin(alias a, alias b)
>> {
>> 	static if (a < b) alias tMin = a; else alias tMin = b;
>> }
>>
>> template tIf(alias cond, args...)
>> {
>> 	enum sp = std.typetuple.staticIndexOf!(tVariadicSplit, args);
>> 	static if (sp < 0) enum spp = args.length; else enum spp = sp;
>>    static if (cond) alias tIf = args[0..tMin!($, spp)];	else 
>> alias tIf = args[tMin!($,spp+1)..$];
>> }
>
> (In your code I suggest to put a newline after each semicolon).
>
> This is one use case, to implement a static ternary operator 
> with multiple arguments. (But having multiple arguments is not 
> so common).
>
> A possible static ternary operator syntax:
>
> enum foo = ct_cond !? Foo!5 : Bar!6;
>

I suggested that a while back.

> But in my opinion the need for it is not strong enough, better 
> to keep the language simpler.
>

Possibly because it doesn't exist? The problem is that when 
working with recursion on variadic parameters you have to deal 
with code like

t!(args[0], args[1..$])

Sometimes you only want to return the last half of the args IF 
something is true, e.g.,

t!(args[0], tIf!(cond, args[1..$-2] else ";"));

or whatever. The problem being that args is a tuple and you can't 
distinguish between what you want to return as true and what you 
want to return as false.

To get around this you either have to create a split manually OR 
write static if's that create a lot of redundant code.

> Do you have a second use case?
>

Then a third? The fact whether there is a use case or not, or 
whether I have one or not should be irrelevant. The issue should 
stand on it's own. Having some easily way to use multiple 
variadic parameters is either useful or not. If it is and not 
hard to implement then it should be implemented. People can't use 
something if it doesn't exist... and will find ways around the 
real problem.


I think with a little work you could come up with many more and 
better use cases than I could.  They all will related to a sort 
of this or that scenario though because else why would one need 
to split up the arguments in the first place if there was no need 
to distinguish the group.

Join!(Strings...; Delims...)

could Join the strings with their Delims.

Map!(Objects...; Funcs...)

Could be an easy way to apply functions to objects.

most of these could be done by using a pair of values though but 
would be easier to use multiple variadics.


Split!(Strings...; Splits...)

could split each strings with all the split possibilities.

e.g.

Split!("abcdefg", "abc"; "b", "c")

will split each string using each split.

returns

(["a", "defg"], ["a"])

Anyways, If you don't build it they won't come...



More information about the Digitalmars-d mailing list