The type of variadic is just [Int]. There's no such type as Int.... Int... declares a parameter with a type of [Int] together with a special flag set that changes the behavior of the function application at the call site.
I wonder why are you saying that? I expected this behaviour!
so "test([1, 2, 3], execute: ... )" outputs "[[1, 2, 3]]" and test(1, 2, 3, execute:) outputs "[1, 2, 3]", totally as I expected.
I'm suggesting we introduce another special flag that distinguishes "Int..." and [Int] inside the function, to get to this behaviour:
I think once same-element requirements are implemented, parameter packs ought to be able to replace most usages of variadic parameters, so it's going to be difficult to justify making any further additions to the legacy feature, especially if they involve major extensions to the type system.
What I found somewhat unexpected is that the three behaviours above are all different...
My personal vote would be for how "Any..." currently works, YMMV.
But that's the bug! (And this kind of ad-hoc behavior is why features like variadic parameters, dynamic Self, etc are bad. If it's just based on some magic flag or type kind that has to be checked and handled specially in certain places, someone will invariably forget.) The behavior in the generic case is the expected behavior. I missed the distinction when reading the original thread.
Huh. Bear in mind that some of us (at least myself!) consider this behaviour the "right" one...
And that fixing this "bug" would be a breaking change...
FWIW I'm with @tera here - it's intuitive and simple for variadics to just work; to be able to pass a variadic argument as a variadic argument, etc. I've always found Swift to be a bit of nightmare when it comes to variadic arguments, because [in Swift] they're so awkward and limited currently, and I actively avoid using them for that reason.
Variadic generics might be technically a superset or superior or whatever, but they're substantially more conceptually & syntactically complex, and I've struggled to use them in real-world code (even aside from them being rather hard to use at all, it always seems to be the case that I hit some known limitation in the current implementation, that is a show-stopper for each use case I've tried - the relatively recent addition of for-loop support is great but addresses only one such hole).
In contrast, Python makes variadics super simple (it requires explicit splatting, but that's fine - I'm not sure it's necessary, but it's not hard nor confusing).
So I don't know what the solution is - e.g. supplant variadic arguments with [better] variadic generics or add explicit splatting or whatever - I just wish this rough patch of the language were cleaned up. Just the other day I needed a wrapper function over print and it was such a ridiculous pain for such a conceptually trivial task.
It would be pretty easy to add a βvariadic splatβ operation, I think the only holdup is the lack of concrete syntax (and perhaps developer cycles).
I agree the parameter pack implementation needs some polish. I think once the gaps are filled in, it will be easier to form a coherent mental model for how it all works.
Sure, but in my experience with C# this leads to problems when you try to pass an array as the only argument to a function that takes a params object[] and it accidentally gets splatted. Bonus points if itβs an optional array and you get a surprise NullReferenceException.
using System;
public class Program {
public static void foo3(params object[] values) {
for (int i = 0; i < values.Length; i++) {
Console.Write(values[i] + " ");
}
Console.WriteLine();
}
public static void Main() {
int[] integers = { 1, 2, 3, 4 };
foo3(integers); // System.Int32[] ONE WAY (IMHO the right way)
object[] objects = { 1, 2, 3, 4 };
foo3(objects); // 1 2 3 4 ANOTHER WAY (IMHO the wrong way)
}
}