[Proposal] Allow passing a variadic parameter to another variadic function

Currently, Swift doesn't have a way to easily pass a variadic parameter to
another variadic function because the variadic parameter itself has already
been collected into an array.

There was a prior posting a few weeks back about allowing arrays to be
passed to a variadic parameter which would resolve this very specific issue:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/015185.html

Unfortunately, that thread devolved into an argument on whether or not
variadic parameters should be removed entirely.

I, certainly, see merit in having functions that can accept a variable
number of arguments and variadic functions should seem intuitive to anyone
else that might be reading the code.

Swift's documentation presents a very intuitive example:

   1. arithmeticMean(1, 2, 3, 4, 5)

It's obvious what this function is doing, and any intelligent person would
expect 3 as the result. Even WolframAlpha knows how to interpret this:

Moreover, a function can only have ONE variadic parameter, which I think
reduces any possible confusion.

Regardless, if variadic parameters are going to stay in Swift, then I think
they should at least support chaining to another function.

The most obvious way of allowing this would be to allow variadic parameters
to accept an array.

However, I think that if an array (of the parameter type) is specified for
a variadic parameter, then no other values should be allowed. This
eliminates any unnecessary complexity of potentially having to add values
to the array.

- Christopher Boyd

Hi Christopher,

Do you think something like this would work if there was a #splat() magic operator like this:

let values = [1, 2, 3, 4, 5]
let mean = arithmeticMean(#splat(values))

···

On May 20, 2016, at 11:19 AM, Christopher Boyd via swift-evolution <swift-evolution@swift.org> wrote:

Currently, Swift doesn't have a way to easily pass a variadic parameter to another variadic function because the variadic parameter itself has already been collected into an array.

There was a prior posting a few weeks back about allowing arrays to be passed to a variadic parameter which would resolve this very specific issue:
[swift-evolution] [Idea] Passing an Array to Variadic Functions

Unfortunately, that thread devolved into an argument on whether or not variadic parameters should be removed entirely.

I, certainly, see merit in having functions that can accept a variable number of arguments and variadic functions should seem intuitive to anyone else that might be reading the code.

Swift's documentation presents a very intuitive example:
arithmeticMean(1, 2, 3, 4, 5)
It's obvious what this function is doing, and any intelligent person would expect 3 as the result. Even WolframAlpha knows how to interpret this: arithmeticMean(1, 2, 3, 4, 5) - Wolfram|Alpha

Moreover, a function can only have ONE variadic parameter, which I think reduces any possible confusion.

Regardless, if variadic parameters are going to stay in Swift, then I think they should at least support chaining to another function.

The most obvious way of allowing this would be to allow variadic parameters to accept an array.

However, I think that if an array (of the parameter type) is specified for a variadic parameter, then no other values should be allowed. This eliminates any unnecessary complexity of potentially having to add values to the array.

- Christopher Boyd
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Ricardo,

That'd work, but I was thinking more along the lines of:
- func add(numbers: Double...) -> Double {
- var total: Double = 0
- for number in numbers {
- total += number
- }
- return total
- }
- func arithmeticMean(numbers: Double...) -> Double {
- return add(numbers) / Double(numbers.count)
- }

Certainly, #splat would work, but it may be slightly more confusing to
someone that hasn't seen the splat operator before:
- func arithmeticMean(numbers: Double...) -> Double {
- return add(#splat(numbers)) / Double(numbers.count)
- }

···

On Fri, May 20, 2016 at 11:52 AM Ricardo Parada <rparada@mac.com> wrote:

Hi Christopher,

Do you think something like this would work if there was a #splat() magic
operator like this:

let values = [1, 2, 3, 4, 5]
let mean = arithmeticMean(#splat(values))

On May 20, 2016, at 11:19 AM, Christopher Boyd via swift-evolution < > swift-evolution@swift.org> wrote:

Currently, Swift doesn't have a way to easily pass a variadic parameter to
another variadic function because the variadic parameter itself has already
been collected into an array.

There was a prior posting a few weeks back about allowing arrays to be
passed to a variadic parameter which would resolve this very specific issue:

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

Unfortunately, that thread devolved into an argument on whether or not
variadic parameters should be removed entirely.

I, certainly, see merit in having functions that can accept a variable
number of arguments and variadic functions should seem intuitive to anyone
else that might be reading the code.

Swift's documentation presents a very intuitive example:

   1. arithmeticMean(1, 2, 3, 4, 5)

It's obvious what this function is doing, and any intelligent person would
expect 3 as the result. Even WolframAlpha knows how to interpret this:
arithmeticMean(1, 2, 3, 4, 5) - Wolfram|Alpha

Moreover, a function can only have ONE variadic parameter, which I think
reduces any possible confusion.

Regardless, if variadic parameters are going to stay in Swift, then I
think they should at least support chaining to another function.

The most obvious way of allowing this would be to allow variadic
parameters to accept an array.

However, I think that if an array (of the parameter type) is specified for
a variadic parameter, then no other values should be allowed. This
eliminates any unnecessary complexity of potentially having to add values
to the array.

- Christopher Boyd

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

[offtopic]

···

On 20.05.2016 19:08, Christopher Boyd via swift-evolution wrote:

Certainly, #splat would work, but it may be slightly more confusing to
someone that hasn't seen the splat operator before:

So, he/she will open swift documentation or drop the question to google once, and from that moment will know what #splat means.
[/offtopic]

Vladimir,

True, but does the extra syntax actually accomplish anything?

From my example:

   - func arithmeticMean(numbers: Double...) -> Double {
   - return add(numbers) / Double(numbers.count)
   - }

It's clear that the intent is to pass all the numbers to add().

What, exactly, does adding the #splat() syntax achieve? It doesn't add any
additional clarity.

Moreover, I don't think #splat has been accepted as a proposal yet.

···

On Fri, May 20, 2016 at 12:19 PM Vladimir.S <svabox@gmail.com> wrote:

[offtopic]
On 20.05.2016 19:08, Christopher Boyd via swift-evolution wrote:
> Certainly, #splat would work, but it may be slightly more confusing to
> someone that hasn't seen the splat operator before:
So, he/she will open swift documentation or drop the question to google
once, and from that moment will know what #splat means.
[/offtopic]

Jaden,

In that very specific example with generics, couldn't you just explicitly
specify foo<[T]>(bar: bar)?

···

On Fri, May 20, 2016 at 12:39 PM <jaden.geller@gmail.com> wrote:

Without it, there could be ambiguity. Observe:

func foo<T>(bar: [T]...) {
  foo(bar: bar) // splat or pass single arg?
}

- Jaden Geller
Sent from my iPhone

On May 20, 2016, at 9:29 AM, Christopher Boyd via swift-evolution < > swift-evolution@swift.org> wrote:

Vladimir,

True, but does the extra syntax actually accomplish anything?

From my example:

   - func arithmeticMean(numbers: Double...) -> Double {
   - return add(numbers) / Double(numbers.count)
   - }

It's clear that the intent is to pass all the numbers to add().

What, exactly, does adding the #splat() syntax achieve? It doesn't add
any additional clarity.

Moreover, I don't think #splat has been accepted as a proposal yet.

On Fri, May 20, 2016 at 12:19 PM Vladimir.S <svabox@gmail.com> wrote:

[offtopic]
On 20.05.2016 19:08, Christopher Boyd via swift-evolution wrote:
> Certainly, #splat would work, but it may be slightly more confusing to
> someone that hasn't seen the splat operator before:
So, he/she will open swift documentation or drop the question to google
once, and from that moment will know what #splat means.
[/offtopic]

_______________________________________________

swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Jaden,

That's a good point.

In C#, variadic parameters explicitly stated to be arrays.

This means that in C#, this never occurs because:
foo(params int bar)
has the same signature as
foo(int bar)

Thus, you can't have both commands defined as they're identified to be
conflicting overloads. In fact, it's what allows you to simply pass an int
array to foo(params int bar).

The params keyword basically just specifies to be an accumulator for
multiple parameters.

Meanwhile, in Swift you can have a single class with all of the following:
foo(bar: Int)
foo(bar: Int...)
foo(bar: [Int])

For the syntax to work without a #splat operator, methods with Int... and
[Int] would have to be considered as equivalent signatures.

···

On Fri, May 20, 2016 at 12:56 PM <jaden.geller@gmail.com> wrote:

Sure, but imagine it weren't generics. Instead, we have two specialized
functions, the first identical the generic one with T = Int and the second
with T = [Int]. We have the same problem again.

Jaden

On May 20, 2016, at 9:50 AM, Christopher Boyd <xpboyd@gmail.com> wrote:

Jaden,

In that very specific example with generics, couldn't you just explicitly
specify foo<[T]>(bar: bar)?

On Fri, May 20, 2016 at 12:39 PM <jaden.geller@gmail.com> wrote:

Without it, there could be ambiguity. Observe:

func foo<T>(bar: [T]...) {
  foo(bar: bar) // splat or pass single arg?
}

- Jaden Geller
Sent from my iPhone

On May 20, 2016, at 9:29 AM, Christopher Boyd via swift-evolution < >> swift-evolution@swift.org> wrote:

Vladimir,

True, but does the extra syntax actually accomplish anything?

From my example:

   - func arithmeticMean(numbers: Double...) -> Double {
   - return add(numbers) / Double(numbers.count)
   - }

It's clear that the intent is to pass all the numbers to add().

What, exactly, does adding the #splat() syntax achieve? It doesn't add
any additional clarity.

Moreover, I don't think #splat has been accepted as a proposal yet.

On Fri, May 20, 2016 at 12:19 PM Vladimir.S <svabox@gmail.com> wrote:

[offtopic]
On 20.05.2016 19:08, Christopher Boyd via swift-evolution wrote:
> Certainly, #splat would work, but it may be slightly more confusing to
> someone that hasn't seen the splat operator before:
So, he/she will open swift documentation or drop the question to google
once, and from that moment will know what #splat means.
[/offtopic]

_______________________________________________

swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Any updates?

There are not ways to pass a variadic argument from one function to another?

Hi @ZheDre1N, please avoid resurrecting 8-year-old threads to ask if there have been any updates—you can feel free to start a new post. Thanks!