[swift-evolution] [Idea] Passing an Array to Variadic Functions

Tony Allevato allevato at google.com
Mon Apr 18 14:01:13 CDT 2016

I would also be supportive of removing varargs for now, in favor of a
rethought design when generics are completed.

In their current form, varargs are fairly limited—because they're mapped
onto an array, the argument types must be homogeneous, so either your
function can only usefully take a single type of argument, or you
potentially lose information because they have to be upcast to a common
supertype or Any in order to build the array.

I'm not convinced that varargs produce code that is much cleaner than the
array version. Is this:

  String(format: "%@ is %d years old", name, age)

that much cleaner than:

  String(format: "%@ is %d years old", arguments: [name, age])

Perhaps slightly, but I'm not sure it's worth the special case. The
function implementor can even get rid of the second argument name if they
wanted to make it cleaner. And if the function you're calling takes varargs
as its sole argument, the only difference is two brackets.

Varargs in their current form seem like a historical vestige from languages
like C and Java where there was no syntax to cleanly create an anonymous
array literal. Swift doesn't have that limitation.

That being said, where varargs *do* become considerably more useful is when
generics are completed and you can have variadic type argument lists. But
in that case, the implementation is completely different because (if Swift
followed C++'s design) you'd be working with a parameter pack instead of an
array, and you would have operations that let you manipulate that pack
while preserving the compile-time type information of those arguments.

IMO, handling it that way seems like a better approach than trying to graft
something to bridge varargs and arrays.

On Mon, Apr 18, 2016 at 11:14 AM Daniel Duan via swift-evolution <
swift-evolution at swift.org> wrote:

> Justin Jia via swift-evolution <swift-evolution at ...> writes:
> >
> > Hi!Currently, we can’t call a variadic function with an array of
> arguments.
> IMO, this would be a useful addition. Here are my thoughts on the thread so
> far as an imaginary Q&A.
> "Why not remove vararg instead?"
> As others have mentioned, this feature enable us to write cleaner code. I
> first learned to appreciate it in C, where some books would introduce it
> as the
> way to implement printf(). I really prefer not to create an array on
> unrelated
> items just to print() them in Swift.
> "Will it be useful in real life?"
> If we keep vararg, then enhancing it with a splat feature will make it far
> more useful than it is today. One of my colleague (hi Scott!) encountered
> its
> limits just last week: once the varadic argumntes becomes an array,
> there's no
> way to get them "back" as arguments. This becomes an issue if our function
> needs to forward part of its received arguments recursively to itself.
> Either
> of the following would be great:
> func foo(a: Int...) {
>     if !a.isEmpty() {
>         apply(foo, a.dropFirst()) // imaginary apply function.
>         foo(a: #splat(a.dropFirst())) // imaginary splat, syntax TBD.
>     }
> }
> Therefore, +1.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160418/7305af10/attachment.html>

More information about the swift-evolution mailing list