Removing Variadic Parameters


(Ted van Gaalen) #1

Thinking a bit longer about functions and parameters…
Swift has excellent facilities for collections and their descendants.

In swift you can easily pack items in array and pass this to a function
instead of a variadic.

Would it be a good idea to remove variadic parameters alltogethery?
This would greatly simplify the function logic.

TedvG


(Tino) #2

It's a late answer… but I wanted to be a good citizen and checked if the topic has been discussed before; so, it seems that is not the case :wink:

In short, I agree:
Variadic parameters are somewhat cool, and I think I was exited when I've seen them in C the first time… but I afair, I never created a variadic function in production code, and I think I just used them for the first time in Swift (I checked wether print is variadic…)
As of today, string interpolation has several advantages over old-style string-formatting, and I can't remember any other method in one of the established libraries that uses this feature:
Explicitly creating an array is just two additional characters, which doesn't matter in a long list (which imho shouldn't be crammed into the function call anyways), and when there are only a few parameters, you can mimic variadics with Optionals defaulted to nil — and who knows what the long-awaited hygienic macros might do to the importance of variadic parameters.

Additionally, variadic parameters compete with trailing closures, which for me would always win the struggle for the last parameter :wink:

As I said, I can't remember a single use case in Swift — and I already utilized quite a lot of the "strange" techniques (currying, tuple splat, complicated combinations of generics & protocols…).
So for me, the answer to the question "would I add this feature to Swift if it wasn't there?" is a clear no…

Tino


(Leonardo Pessoa) #3

-1_000_000_000

I believe variadic parameters are useful in a range of situations and
I use them myself a lot. As you mentioned yourself, you never created
variadic functions and you are allowed to continue working like that
for as long as it suits you so. It is a choice and you and other
developers are allowed to decide when and where to use it. As for
trailing closures, just as Saagar mentioned, your variadic parameter
does not have to be the last one, as it has to in C, and thus they do
not compete. Give it a try.

L

···

On 6 July 2016 at 15:49, Saagar Jha via swift-evolution <swift-evolution@swift.org> wrote:

On Wed, Jul 6, 2016 at 11:38 AM Tino Heth via swift-evolution > <swift-evolution@swift.org> wrote:

It's a late answer… but I wanted to be a good citizen and checked if the
topic has been discussed before; so, it seems that is not the case :wink:

In short, I agree:
Variadic parameters are somewhat cool, and I think I was exited when I've
seen them in C the first time… but I afair, I never created a variadic
function in production code, and I think I just used them for the first time
in Swift (I checked wether print is variadic…)
As of today, string interpolation has several advantages over old-style
string-formatting, and I can't remember any other method in one of the
established libraries that uses this feature:
Explicitly creating an array is just two additional characters, which
doesn't matter in a long list (which imho shouldn't be crammed into the
function call anyways), and when there are only a few parameters, you can
mimic variadics with Optionals defaulted to nil — and who knows what the
long-awaited hygienic macros might do to the importance of variadic
parameters.

Additionally, variadic parameters compete with trailing closures, which
for me would always win the struggle for the last parameter :wink:

Actually, you don’t have to make a variadic parameter last…print doesn’t.

As I said, I can't remember a single use case in Swift — and I already
utilized quite a lot of the "strange" techniques (currying, tuple splat,
complicated combinations of generics & protocols…).
So for me, the answer to the question "would I add this feature to Swift
if it wasn't there?" is a clear no…

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

--
-Saagar Jha

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


(Saagar Jha) #4

It's a late answer… but I wanted to be a good citizen and checked if the
topic has been discussed before; so, it seems that is not the case ;-)

In short, I agree:
Variadic parameters are somewhat cool, and I think I was exited when I've
seen them in C the first time… but I afair, I never created a variadic
function in production code, and I think I just used them for the first
time in Swift (I checked wether print is variadic…)
As of today, string interpolation has several advantages over old-style
string-formatting, and I can't remember any other method in one of the
established libraries that uses this feature:
Explicitly creating an array is just two additional characters, which
doesn't matter in a long list (which imho shouldn't be crammed into the
function call anyways), and when there are only a few parameters, you can
mimic variadics with Optionals defaulted to nil — and who knows what the
long-awaited hygienic macros might do to the importance of variadic
parameters.

Additionally, variadic parameters compete with trailing closures, which
for me would always win the struggle for the last parameter ;-)

Actually, you don’t have to make a variadic parameter last…print doesn’t.

···

On Wed, Jul 6, 2016 at 11:38 AM Tino Heth via swift-evolution < swift-evolution@swift.org> wrote:

As I said, I can't remember a single use case in Swift — and I already
utilized quite a lot of the "strange" techniques (currying, tuple splat,
complicated combinations of generics & protocols…).
So for me, the answer to the question "would I add this feature to Swift
if it wasn't there?" is a clear no…

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

--
-Saagar Jha


(Tino) #5

I believe variadic parameters are useful in a range of situations and
I use them myself a lot.

Can you talk about concrete examples? Because Objective-C had no variadic messages, it's natural that the feature isn't utilized in Cocoa, but I doubt that it is used by many native Swift libraries either.

I'm the last one to take away something that doesn't hurt, but so far, several (in my opinion) useful features have been removed with the option to reintroduce them later — and at least tuple splat really had unique aspects (compared to variadics, which are just a small dose of syntactic sugar).


(David Rönnqvist) #6

I'd be reluctant to remove variadic parameters. We've found on our team that variadic arguments are easier to read on the call site compared to array arguments, especially when it's common to pass a single value (but still possible to pass multiple values).

- David

···

On 6 Jul 2016, at 20:38, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

It's a late answer… but I wanted to be a good citizen and checked if the topic has been discussed before; so, it seems that is not the case :wink:

In short, I agree:
Variadic parameters are somewhat cool, and I think I was exited when I've seen them in C the first time… but I afair, I never created a variadic function in production code, and I think I just used them for the first time in Swift (I checked wether print is variadic…)
As of today, string interpolation has several advantages over old-style string-formatting, and I can't remember any other method in one of the established libraries that uses this feature:
Explicitly creating an array is just two additional characters, which doesn't matter in a long list (which imho shouldn't be crammed into the function call anyways), and when there are only a few parameters, you can mimic variadics with Optionals defaulted to nil — and who knows what the long-awaited hygienic macros might do to the importance of variadic parameters.

Additionally, variadic parameters compete with trailing closures, which for me would always win the struggle for the last parameter :wink:

As I said, I can't remember a single use case in Swift — and I already utilized quite a lot of the "strange" techniques (currying, tuple splat, complicated combinations of generics & protocols…).
So for me, the answer to the question "would I add this feature to Swift if it wasn't there?" is a clear no…

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


(L Mihalkovic) #7

Even vb does that... If you ever want to write a compiler or anything that has to dynamically adjust its behavior (which i would expect most objc devs never do) then it might be useful to not cut all the claws of this tigger.
Regards
LM
(From mobile)

···

On Jul 6, 2016, at 8:38 PM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

It's a late answer… but I wanted to be a good citizen and checked if the topic has been discussed before; so, it seems that is not the case :wink:

In short, I agree:
Variadic parameters are somewhat cool, and I think I was exited when I've seen them in C the first time… but I afair, I never created a variadic function in production code, and I think I just used them for the first time in Swift (I checked wether print is variadic…)
As of today, string interpolation has several advantages over old-style string-formatting, and I can't remember any other method in one of the established libraries that uses this feature:
Explicitly creating an array is just two additional characters, which doesn't matter in a long list (which imho shouldn't be crammed into the function call anyways), and when there are only a few parameters, you can mimic variadics with Optionals defaulted to nil — and who knows what the long-awaited hygienic macros might do to the importance of variadic parameters.

Additionally, variadic parameters compete with trailing closures, which for me would always win the struggle for the last parameter :wink:

As I said, I can't remember a single use case in Swift — and I already utilized quite a lot of the "strange" techniques (currying, tuple splat, complicated combinations of generics & protocols…).
So for me, the answer to the question "would I add this feature to Swift if it wasn't there?" is a clear no…

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


(Rob Mayoff) #8

Objective-C has variadic messages. I'd be surprised if any seasoned
Objective-C developer hasn't used `+[NSString stringWithFormat:]`.

These are most of the variadic messages in the El Capitan SDK:

-[NSGradient initWithColorsAndLocations:]
-[AMAction logMessageWithLevel:format:]
-[CIFilter apply:]
+[CISampler samplerWithImage:keysAndValues:]
-[CISampler initWithImage:keysAndValues:]
+[NSArray arrayWithObjects:]
-[NSArray initWithObjects:]
-[NSCoder encodeValuesOfObjCTypes:]
-[NSCoder decodeValuesOfObjCTypes:]
+[NSDictionary dictionaryWithObjectsAndKeys:]
-[NSDictionary initWithObjectsAndKeys:]
+[NSException raise:format:]
-[NSException handleFailureInMethod:object:file:lineNumber:description:]
-[NSException handleFailureInFunction:file:lineNumber:description:]
+[NSExpression expressionWithFormat:]
+[NSOrderedSet orderedSetWithObjects:]
-[NSOrderedSet initWithObjects:]
+[NSPredicate predicateWithFormat:]
+[NSSet setWithObjects:]
-[NSSet initWithObjects:]
-[NSString stringByAppendingFormat:]
-[NSString initWithFormat:]
-[NSString initWithFormat:locale:]
+[NSString stringWithFormat:]
+[NSString localizedStringWithFormat:]
-[NSString appendFormat:]
-[SBObject sendEvent:id:parameters:]

···

On Wed, Jul 6, 2016 at 2:57 PM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

Can you talk about concrete examples? Because Objective-C had no variadic messages, it's natural that the feature isn't utilized in Cocoa


(Haravikk) #9

I'm very much in the remove-them camp, however I do wonder if there might be another way to handle them? In other words, when defining a method we should always define an array, but perhaps we could use an attribute to selectively turn any Sequence or Iterator parameter into a variadic, like-so:

  func someMethod(@variadic _ values:[Int]) { … }

This can be called using the developers preference between:

  someMethod([1, 2, 3, 4, 5, 6])
  someMethod(1, 2, 3, 4, 5, 6)

So long as there's no ambiguity of course. This should have a few advantages over the current variadics:

No unique declaration syntax
Reinforces that a variadic function is just a function taking some kind of Collection
Enables us to choose the type of the parameter from any Iterator, Sequence or Collection.
Allows developers to choose the function's form at the call-site between passing a collection/sequence/iterator or a list of values. Also an array literal if the chosen type supports that as in the example above.
Allows passing of an array literal or appropriate Collection type.
An attribute is more discoverable (option-click in Xcode to view documentation).

Any got any thoughts on this alternative?

···

On 6 Jul 2016, at 21:13, David Rönnqvist via swift-evolution <swift-evolution@swift.org> wrote:

I'd be reluctant to remove variadic parameters. We've found on our team that variadic arguments are easier to read on the call site compared to array arguments, especially when it's common to pass a single value (but still possible to pass multiple values).

- David


(Tino) #10

Objective-C has variadic messages. I'd be surprised if any seasoned

my fault — how could I forget those nil-terminated array-initializers? :wink:
Yes, Objective-C had variadics, but imho they have been much worse than in Swift.


(David Rönnqvist) #11

That’s a possibility (at least for our use case).

In our closed-source project we have 17 functions that take variadic parameters. In all cases it’s done that way because it’s possible for the caller to pass a comma separated list of values but the most common case is to only pass a single argument. Additionally, we might want to enforce that at least one value is passed (using a single value parameter and an unlabeled variadic parameter after that).
(the example below is Swift 2.2 syntax)

// requires zero or more arguments
func foo(xs: Int ...) {}

// requires one or more arguments
func bar(x: Int, _ xs: Int ...) {}

The second case would looks really strange without the variadic parameter (calling site) syntax and it would no longer look like it’s one continuous list of values.

As long as we can keep the call site syntactical benefits of variadic parameters and do thing like the above, I’m fine with changing the way it’s defined / works internally.
  
- David

···

On 07 Jul 2016, at 10:07, Haravikk <swift-evolution@haravikk.me> wrote:

On 6 Jul 2016, at 21:13, David Rönnqvist via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I'd be reluctant to remove variadic parameters. We've found on our team that variadic arguments are easier to read on the call site compared to array arguments, especially when it's common to pass a single value (but still possible to pass multiple values).

- David

I'm very much in the remove-them camp, however I do wonder if there might be another way to handle them? In other words, when defining a method we should always define an array, but perhaps we could use an attribute to selectively turn any Sequence or Iterator parameter into a variadic, like-so:

  func someMethod(@variadic _ values:[Int]) { … }

This can be called using the developers preference between:

  someMethod([1, 2, 3, 4, 5, 6])
  someMethod(1, 2, 3, 4, 5, 6)

So long as there's no ambiguity of course. This should have a few advantages over the current variadics:

No unique declaration syntax
Reinforces that a variadic function is just a function taking some kind of Collection
Enables us to choose the type of the parameter from any Iterator, Sequence or Collection.
Allows developers to choose the function's form at the call-site between passing a collection/sequence/iterator or a list of values. Also an array literal if the chosen type supports that as in the example above.
Allows passing of an array literal or appropriate Collection type.
An attribute is more discoverable (option-click in Xcode to view documentation).

Any got any thoughts on this alternative?


(Tino) #12

The second case would looks really strange without the variadic parameter (calling site) syntax and it would no longer look like it’s one continuous list of values.

agreed, that would be odd — but I really hope that there will be a nice alternative in the future.

One very fundamental thing is missing in Swift: Fixed-size arrays.

I can't predict if or how this issue will be tackled, but the most elegant way I can see would be generic values:
let array: Array<size: 5, Int>
If this happens, it should be possible to create arrays with a minimal size as well — and additionally, you could impose other restrictions (max length, even number of elements, length mod x = n…).

I repeat that this is all speculation, and it might never happen… but would you be fine with this alternative?