I read the proposal and began reading the thread until I realized how long it is and that I don't have time to read every comment, so I'm sorry if my question is already answered somewhere that I have missed.
I found my way to this page because a feature which I am currently in need of could be very nicely served by variadic generics, but from what I could understand from the proposal, the proposed implementation would not meet my need. What I want (I think this is a coherent request) is to be able to use a variadic associated type to declare a set of functions, one for each type in the vector. For example:
protocol Eater {
associatedtype ...Foods: Digestible
var carbs: Int { get set }
var fats: Int { get set }
var proteins: Int { get set }
}
extension Eater {
mutating func ...eat (_ food: Foods...) {
self.carbs += food.carbs
self.fats += food.fats
self.proteins += food.proteins
}
}
Notice the elipsis before the name of the function, but not before the function parameter name. This is because the parameter is singular, and it is the function declarations which are multiple in order to match the arity of the vector. I would define some Digestible
types (pretend that they conform):
enum Fruit: Digestible {
case apple
case strawberry
case banana
case kiwi
}
enum Vegetable: Digestible {
case broccoli
case spinach
case zucchini
case squash
}
And then could define a type which conforms to Eater
:
struct Vegetarian: Eater {
typealias ...Foods = <Fruit, Vegetable>
var carbs: Int = 0
var fats: Int = 0
var proteins: Int = 0
}
And use it like this:
let joe = Vegetarian()
joe.eat(.zucchini)
joe.eat(.kiwi)
In this toy example, the Digestible
protocol does not have associated types and therefore the Eater
type could of course just put the same implementation under this function signature:
func eat (_ food: Digestible) { ... }
or if it did have associated types it could be written like this:
func eat <Food: Digestible> (_ food: Food, using recipe: Food.IdealRecipe) { ... }
but the MAJOR drawback here is that the types are no longer constrained, which leads to a few problems for me, the most dire of which is that autocomplete will no longer help me. The workflow which I have been working extremely hard to refine and perfect is one which makes heavy use of autocomplete and type inference, such that when I am figuring out which input to provide to a given function, I just type a .
and autocomplete immediately springs into action and gives a concise list of my exact options with this function in this particular context. I cannot understate the leaps and bounds in workflow that this produces. Without this, my code in this example would be:
joe.eat(Vegetable.zucchini)
joe.eat(Fruit.kiwi)
and I would have to remember the names of the types I want to use.
Has anyone put thought toward this type of use case for variadic generic parameters? To me, this is not a niche or trivial ability that is gained. If this were possible, my library would enable such a new level of effortlessness in development due to the beauty of autocomplete showing me my exact options all over the place. Right now I'm resorting to code generation to get the job done - perhaps when my library is in more of a working condition I can post about it to hopefully prove that there is great utility in this use case.
P.S. I'm aware that on top of the main syntax I'm proposing here I have also introduced this syntax typealias ...Foods = <Fruit, Vegetable>
. As far as I can tell from the proposal, the only way to satisfy the requirements of a protocol with a variadic associated type is for the conforming type to also have a variadic generic parameter list, but what if I want to create a non-generic type which conforms to a protocol with a variadic associated type, as in my example? There's gotta be a way to do that.