I'm for manual splatting.
Do you think that you should be able to splat any Collection
?
Array splatting is the big win here, and moving from only being able to splat arrays to being able to splat arbitrary collections isn't source breaking, so I think we should leave out the more general version unless we have an actual use case for it.
I don’t think we should support all Collection
s. Supporting Array
has no performance impact, since variadic arguments are already passed in an Array
. Supporting all Collection
s means constructing a temporary Array
(costs in performance) or redesigning variadic arguments to support any Collection
(costs in design time, implementation time, and probably performance too).
I second this, for a different reason:
We have to assume that parameter order matters, even for variadic functions. Giving the ability to splat non-ordered collections will just lead to bugs that would otherwise be really obvious to avoid.
We should also ensure that an error message is thrown if someone does indeed input a variable holding Variadic<Int>
that they need to splat it before putting it into a parameter holding Int...
(Variadic<Int>
).
Why would it be an error? Perhaps I'm missing something, but wouldn't Variadic
, as proposed, be a fully-qualified type? Why would it be restricted in this way?
So @Avi, would you say that the only circumstances that require manual splatting should be those where the variadic parameter itself cannot hold a variadic values (check the following example)
// for the purpose of the argument,`doSomethingWithAnyCollection` or `doSomethingWithACollection <T: Collection>(_ arg: T)`
func doSomethingWithAny(_ arg: VariadicArray<Any>) { // could have also wrote Any...
let count = arg.count
print(count)
}
What would you say should happen if I do this:
let slightlyProblematicVariadic : VariadicArray<Any> = [3, true, "Marvin", "Sally", -12439.2349332, false]
doSomethingWithAny(slightlyProblematicVariadic)
What should be printed, 1
or 6
?
What about if I do:
let slightlyProblematicVariadic : VariadicArray<Any> = [3, true, "Marvin", "Sally", -12439.2349332, false]
let anotherProblematicVariadic : VariadicArray<Any> = [false, "Joe", 23, "Allan", true, 47.4951]
doSomethingWithAny(slightlyProblematicVariadic, anotherProblematicVariadic)
What should happen in this case too?
The opposite. If the type can hold a variadic, it requires manual splatting to explicitly declare the desired behavior at the call site. If you don't do this, there would be no way to pass a VariadicArray
as a single parameter to such methods.
You could make it a rule: VariadicArray
is always splatted, and to avoid this, wrap the value in Array()
at the call site. But, can this be optimized out at compile time? An explicit splat of VariadicArray
is handled at compile time, because it directs the compiler to not wrap the VariadicArray
into another VariadicArray
. Forcing the call site to invoke Array()
would either need special compiler magic, or it would happen at runtime.
I think in this case "6" would be printed, as you are passing a Variadic<Any>
to a function taking a Variadic<Any>
In this case, I would say "2" would be printed, as you are passing Variadic<Variadic<Any>>
to a function accepting Variadic<Any>
.
That's what I would expect, too.
Should a parameter of Int…
accept a variable holding a VariadicSet<Int>
as well as VariadicArray<Int>
. But if a variable is not explicitly declared I think that it should be inferred to be a VariadicArray
, leaving VariadicSet
s to require explicit type inference as is the same in the declaration of Set
s and Array
s
aRandomVariadic = 1,2,3,4,5,6 //Inferred to be VariadicArray<Int>
Lastly, I think the shorthand, T…
should be restricted to use only in functions as parameters that can reference VariadicArray
s and VariadicSet
s. Like the equivalent of writing the hypothetical AnyVariadic
in this case.