Sent from my iPad
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'
What is the rationale here? Vector makes some sense for the parameter packs because they only consist of types and are thus homogenous. But value packs and argument packs will consist of values or arguments that might all have different types. They are heterogeneous. So vector doesn't seem like the right term. It's not a huge deal, but something to consider anyway.
The intended meaning is that a value vector is homogeneous in the sense that all its members are values.
Makes sense when you look at just the fact that they are values and don't consider what kind of value I guess.
Ā·Ā·Ā·
Sent from my iPad
On May 29, 2016, at 10:14 PM, Austin Zheng <austinzheng@gmail.com> wrote:
On May 29, 2016, at 8:04 PM, Matthew Johnson <matthew@anandabits.com> wrote:
On May 29, 2016, at 7:36 PM, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:
That being said, I don't feel much at all about the naming either way. The "rationale" was that maybe changing 'pack' to a different word would help avoid scaring off people still scarred by C++ templates :). Not really a compelling reason to be honest.
Austin
By the way, the multiMap example is basically the same as the applicative functor for ZipList in Haskell (Functors, Applicative Functors and Monoids - Learn You a Haskell for Great Good!). You can probably find several more good examples by looking at other applicative functors.
Still thinking about more robust function forwarding but not making much progress...
- 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@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:
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' functionThere 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: Draft RFC: variadic generics Ā· Issue #376 Ā· rust-lang/rfcs Ā· GitHub
Feedback would be greatly appreciated. Again, be unsparing.
Best,
Austin_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution