[Pitch] Parameter Packs

There's an innate conflict here between the declaration of a pack, where the name stands for a sequence and it feels right to pluralize it (e.g. Widgets), and the uses of a pack, where the name is always part of an expansion and stands for one component and so feels like it ought to be singular (e.g. Widget). This is a place where experience with a similar feature (e.g. from C++) could potentially be very helpful; unfortunately, as someone with that experience, I can tell you that I've never found an appealing resolution to that conflict, so my experience is in fact not helpful at all.

Now, this conflict would be resolved if we allowed the use site to bind a different name to the pack element. I can think of a couple different syntaxes for that:

  • for A in Arguments { A? }
  • each A in Arguments { A? }
  • Arguments.map { A in A? }

I don't love any of them, though. And in context, I worry that people won't understand that this is an expansion, so maybe they also need a trailing ..., which just makes the syntax worse. They're also a little awkward when it comes to expanding multiple packs in parallel — the first two, I can imagine something with parens, but for .map I really don't know.

Maybe the biggest problem is that this feels really heavyweight when you're just trying to expand the pack directly, which is very common. That's especially true in variadic generic functions, where we probably declare the type parameter pack T and then immediately turn around and declare a value parameter pack of type T..., or a single parameter of type Stream<T...>, or whatever. It's interesting to note that the naming issue disappears here, too: there's nothing misleading or confusing about just writing Arguments.... So if we can settle on a binding/mapping expansion syntax, maybe we can hybridize that syntax with ..., so that ... when the operand is directly a pack reference means a direct pack expansion without any mapping, and otherwise you have to use the binding/mapping syntax.

(This would also eliminate the formal ambiguities with ..., since you could only use it directly on pack references, which would otherwise be ill-formed. If you wanted to write a pack expansion of half-open ranges, you could just write each lowerBound in args { lowerBound... }.... It would still be visually ambiguous, of course.)

This would also give us a syntax for the dreaded "type of pack expansion no longer refers to a pack" problem, e.g. the type of collections.count..., where every component is concretely an Int but the expression is still a pack expansion.

3 Likes