www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - Relax template sequence parameters, explicit template sequence

reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
prev sibling parent monkyyy <crazymonkyyy gmail.com> writes:
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 arguments
 void 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