[swift-evolution] Variadic generics discussion

Austin Zheng austinzheng at gmail.com
Sun May 29 19:36:46 CDT 2016

I significantly rewrote the proposal to take into account as much feedback as I could. (Many things, like syntax, haven't been changed yet, but will be in a forthcoming version.)

What I did change:

- Renamed 'packs' to 'vectors'
- Discussed variadic typealiases a bit, including things like "variadic String" for holding the results of vector computations
- There's a "every variadic associated type must be equal" constraint that can be defined now
- I added a section discussing a "fold" operation, to reduce a value pack/value vector into a single scalar with the help of a user-defined function.
- I changed the proposal so that making a tuple out of a vector now requires surrounding the vector with #tuple(), to get rid of the 'implicit' rules that plx brought up
- I added a section briefly discussing how this feature might be implemented.

Some thoughts:

- Things like indexing into a value vector by an integer value would be extremely powerful. But as far as I can tell they'd require a great deal of macro-like functionality to go along with them. A way to define constant expressions would be required, so we could define "#index = #count(T...)" or something. Then we'd need ways to manipulate that value (increment or decrement) if we wanted to work with the previous or next elements in a chain, we'd need compile-time conditional checking so that a variadic generic could behave correctly for the first or last item in a vector, and so forth. Omitting these expensive features is going to limit the number of uses variadic generics have; is this tradeoff going to be worth it? Could we push off those features to a later date, if/when Swift gets an actual compile time metaprogramming design?

- The more I think about things, the more I'm leaning towards the idea that tuples are the only construct necessary. We could get rid of most of the features of value packs/vectors, and allow them to only serve two roles: defining a variadic generic function, and spreading out a tuple in order to call a variadic generic function. (I think I prefer a spreading operator to bringing back the magic compiler tuple splat functionality.) They could also be "spread out" to define or specialize a different variadic generic type. Thoughts?

- With the existence of 'fold', might it be worth it to remove #tail() (and maybe #head), at least from v1? This would represent a slight loss of expressive power for common use cases in exchange for a considerable decrease in complexity.

Alternatively, some tuple-based designs might make this point obsolete. Imagine something like this:

func head<T, ...U>(input: (T, U...)) -> T { ... }
func tail<T, ...U>(input: (T, U...)) -> (U...) { ... }

Again, any comments are welcome. I hope to continue evolving this proposal as the community decides what they want and don't want to see.

> On May 28, 2016, at 1:03 PM, Austin Zheng <austinzheng at gmail.com> wrote:
> Hello swift-evolution,
> I put together a draft proposal for the variadic generics feature described in "Completing Generics" as a major objective for Swift 3.x. It can be found here:
> https://github.com/austinzheng/swift-evolution/blob/az-variadic-generics/proposals/XXXX-variadic-generics.md <https://github.com/austinzheng/swift-evolution/blob/az-variadic-generics/proposals/XXXX-variadic-generics.md>
> It adopts the syntax and semantics that are described in Completing Generics, and attempts to remain as simple as possible while still being useful for certain use cases (although I think there is still room to simplify). The proposal contains sample implementations for four use cases:
> - Arbitrary-arity 'zip' sequence
> - Arbitrary-arity tuple comparison for equality
> - Tuple splat/function application
> - Multiple-arity Clojure-style 'map' function
> There is a lot of scope for design refinements, and even for alternative designs. With enhanced existentials, there was already an informal consensus that the feature would involve composing some protocols and class requirements, and placing constraints on the associated types, and most everything else was working out the various implications of doing so. That's not true for this feature.
> In particular, I'm interested to see if there are similarly expressive designs that use exclusively tuple-based patterns and no parameter packs. I think Rust once considered a similar approach, although their proposal ended up introducing a parameter-pack like construct for use with fn application: https://github.com/rust-lang/rfcs/issues/376 <https://github.com/rust-lang/rfcs/issues/376>
> Feedback would be greatly appreciated. Again, be unsparing.
> Best,
> Austin

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160529/fccbddac/attachment.html>

More information about the swift-evolution mailing list