digitalmars.dip.ideas - Relax template sequence parameters, explicit template sequence
- Quirin Schroll (50/50) Feb 19 Template sequence parameters (`Ts...`) must be the last parameter
- Jonathan M Davis (10/60) Feb 19 Because !() is already used for instantiating templates, I don't see how
- monkyyy (24/30) Feb 19 ```d
Template sequence parameters (`Ts...`) must be the last parameter of a template. That also means one can only have one of them per template. To facilitate passing a sequence to a sequence parameter, a new syntactical construct is needed. For simplicity, I’ll use `!()`. It would only be needed if a template with a non-terminal sequence parameter is explicitly instantiated. ```d void f(Ts..., Rs...)(Ts ts, Rs rs) { } ``` ```d f(); // Ts = !(), Rs = !() f(1,2,3); // Ts = !(int, int, int), Rs = !() f!(!(int))(1,2,3); // Ts = !(int), Rs = !(int, int) f!(!(int), !(int, long))(1,2,3); // Ts = !(int), Rs = !(int, long) f!(!int, int, long)(1,2,3); // Ts = !(int), Rs = !(int, long) // The `()` are optional if it’s a single token // The last sequence matches individually stated arguments (current behavior) ``` Other use case: Make it hard to pass certain arguments ```d void f(Ts..., size_t line = __LINE__)(Ts args) { pragma(msg, line); } ``` ```d f!(int, int)(1, 2); // good, Ts = !(int, int) f!(int, int, 0)(1, 2); // error, tries Ts = !(int, int, 0), but `0` is not a type f!(!(int, int), 0)(1, 2); // good (won’t happen by accident) ``` Note: `!(Args…)` would not produce an `AliasSeq!(Args…)`. It’d be part of the template argument list syntax: ```diff TemplateInstance: Identifier TemplateArguments TemplateArguments: ! ( ) ! ( TemplateArgumentList ) ! TemplateSingleArgument TemplateArgumentList: TemplateArgument TemplateArgument , TemplateArgument , TemplateArgumentList TemplateArgument: Type AssignExpression Symbol + TemplateArguments ```
Feb 19
On Wednesday, February 19, 2025 8:46:08 PM MST Quirin Schroll via dip.ideas wrote:Template sequence parameters (`Ts...`) must be the last parameter of a template. That also means one can only have one of them per template. To facilitate passing a sequence to a sequence parameter, a new syntactical construct is needed. For simplicity, I’ll use `!()`. It would only be needed if a template with a non-terminal sequence parameter is explicitly instantiated. ```d void f(Ts..., Rs...)(Ts ts, Rs rs) { } ``` ```d f(); // Ts = !(), Rs = !() f(1,2,3); // Ts = !(int, int, int), Rs = !() f!(!(int))(1,2,3); // Ts = !(int), Rs = !(int, int) f!(!(int), !(int, long))(1,2,3); // Ts = !(int), Rs = !(int, long) f!(!int, int, long)(1,2,3); // Ts = !(int), Rs = !(int, long) // The `()` are optional if it’s a single token // The last sequence matches individually stated arguments (current behavior) ``` Other use case: Make it hard to pass certain arguments ```d void f(Ts..., size_t line = __LINE__)(Ts args) { pragma(msg, line); } ``` ```d f!(int, int)(1, 2); // good, Ts = !(int, int) f!(int, int, 0)(1, 2); // error, tries Ts = !(int, int, 0), but `0` is not a type f!(!(int, int), 0)(1, 2); // good (won’t happen by accident) ``` Note: `!(Args…)` would not produce an `AliasSeq!(Args…)`. It’d be part of the template argument list syntax: ```diff TemplateInstance: Identifier TemplateArguments TemplateArguments: ! ( ) ! ( TemplateArgumentList ) ! TemplateSingleArgument TemplateArgumentList: TemplateArgument TemplateArgument , TemplateArgument , TemplateArgumentList TemplateArgument: Type AssignExpression Symbol + TemplateArguments ```Because !() is already used for instantiating templates, I don't see how this could be anything other than confusing. And while it would occasionally be useful to have multiple variadic lists of template parameters or arguments, it really doesn't come up very often. So, I question that complicating the language further to support them is worth it. As it is, you can always just wrap them in another template if you really need them. What are trying to do where something like this would really be needed? - Jonathan M Davis
Feb 19
On Thursday, 20 February 2025 at 03:46:08 UTC, Quirin Schroll wrote:Template sequence parameters (`Ts...`) must be the last parameter of a template. That also means one can only have one of them per template.```d template foo(T...){ template foo(S...){ void foo(U...)(){ T.stringof.writeln; S.stringof.writeln; U.stringof.writeln; }}} unittest{ alias a=foo!(int,float); alias b=a!bool; b!(1); } ``` If the "multi template argument" thing was removed it would just work ---Other use case: Make it hard to pass certain argumentsvoid f(Ts..., size_t line = __LINE__)(Ts args) { pragma(msg, line); }Should just remove the restriction that ... must come last ``` void foo(T...,A...,R)(R r,A args,int line=__LINE__){...} buzz.foo!(bar,fizz)(1,2,3);// r=buzz,T=bar,fizz,args=1,2,3 ```
Feb 19