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









Jonathan M Davis <newsgroup.d jmdavisprog.com> 