On Tuesday, 3 November 2020 at 07:05:19 UTC, Manu wrote:
> There's a grammar change that supports:
> alias staticMap(F, Args...) = F!Args...;
> And also:
> MyTemplate!(expr...) <-- appearance in template parameter
> lists
>
> It's also deliberate and necessary that the grammar is NOT
> modified such
> that `...` could be accepted in argument list definitions, [...]
> I actually really like this incidental restriction; it makes
> declarations clearer.
I really don't think that such a special case is necessary. Maybe
one way to litigate this is to (using terms just learned from
Andrei) require the pattern to be in parentheses. Since
`identifier...` (where identifier is a tuple) is the same as
`identifier` per se, one could solve the question how long the
`...` expands to the right by requiring parentheses. No one ever
asked how far template arguments are read, i.e. whether T!Arg[0]
means (T!Arg)[0] or T!(Arg[0]) because it is single token or you
need parentheses. Not even T![0,1,2] (an array literal) compiles!
So... maybe it is (pattern)... that is The Right Thing™? That
way, you can have it in function parameter lists:
void func((pattern)... args) { .. }
An example would be
void func(Ts...)((Ts[])... args) { .. }
for a function template taking any kinds of slices. It is
unambiguous because the parentheses aren't legal in current state
of D.
Good point. Except elipsis would be inside the parens.
That is absolutely possible, and it might even already just happen to work because how the grammar is naturally.
Notice that `const(Ts)...` is still the old syntax, i.e. the
`...` are for type-safe variadic parameters. Full example:
https://run.dlang.io/is/3QvFCA
Since there are types like int* that can be expressed with a
token sequence that aren't legal as expressions, there is a need
for type patterns and expression patterns; or patterns in general
must accommodate types and expressions together.