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

Dave Abrahams dabrahams at apple.com
Mon Apr 18 17:41:34 CDT 2016


on Fri Apr 15 2016, Justin Jia <swift-evolution at swift.org> wrote:

> Hi!
>
> Currently, we can’t call a variadic function with an array of arguments.
>
> Reference:
> 1. http://stackoverflow.com/questions/24024376/passing-an-array-to-a-function-with-variable-number-of-args-in-swift
> 2. https://www.drivenbycode.com/the-missing-apply-function-in-swift/
>
> Consider the following use case:
>
> ```
> func average(numbers: Double…) -> Double {
>     return sum(numbers) / numbers.count // Error: Cannot convert value of type ‘[Double]’ to expected argument type ‘Double'
> }
>
> func sum(numbers: Double...) -> Double { … }
> ```
>
> Right now, there are two ways to fix it:
>
> 1. Add another function that accept `[Double]` as input.
>
> ```
> func average(numbers: Double…) -> Double {
>     return sum(numbers) / numbers.count
> }
>
> func sum(numbers: Double...) -> Double {
>     return sum(numbers)
> }
>
> func sum(numbers: [Double]) -> Double { … }
> ```
>
> 2. Implement an `apply()` function using `unsafeBitCast`.
>
> ```
> func average(numbers: Double…) -> Double {
>     return sum(apply(numbers)) / numbers.count
> }
>
> func sum(numbers: [Double]) -> Double { … }
>
> func apply<T, U>(fn: (T...) -> U, args: [T]) -> U {
>     typealias FunctionType = [T] -> U
>     return unsafeBitCast(fn, FunctionType.self)(args)
> }
> ```
>
> However, both solutions are not very elegant. The first solution
> requires the library author to implement both functions, and the
> second solution breaks the guarantees of Swift’s type system.
>
> Swift should allow passing an array to variadic functions, or we
> should implement a type-safe `apply()` function in the standard
> library.

Yes, having a way to forward an array to a variadic function is
something we've always wanted but have never gotten around to
implementing.

-- 
Dave



More information about the swift-evolution mailing list