[Idea] Passing an Array to Variadic Functions

Just annotenhere: String intepolation is ok for logging purposes but not for creating user messages which have to be localized (with possibly having to reorder the parameters).

Clever use of StringInterpolationConvertible, as demonstrated in my example code, can make it suitable.

···

Sent from my iPad

Just annotenhere: String intepolation is ok for logging purposes but not for creating user messages which have to be localized (with possibly having to reorder the parameters).

Reordering is not a problem

if language == “fr"
{
    object = “me”
    verb = “lance"
}
else
{
    object = “myself”
    verb = “throw"

}

“Je \(object) \(verb) vers la gloire”
“I \(verb) \(object) towards glory"

There are other issues though (e.g. format should be in the hands of the translator) which mean I would not want to lose format strings.

···

On 19 Apr 2016, at 10:41, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

-Thorsten

Am 18.04.2016 um 22:56 schrieb Dennis Weissmann via swift-evolution <swift-evolution@swift.org>:

- Dennis

On Apr 18, 2016, at 9:55 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I would like to see format strings go away and be replace with safer inline annotations.

The main problem is doing localized strings with printf-style formats well, but I actually have a pretty sweet solution for that: https://gist.github.com/brentdax/79fa038c0af0cafb52dd

-- E, somewhat agnostic on variadics

Variadics are eventually important as a generic function feature; you really want to be able to write a version of zip() which can take any number of sequences, for instance, and the only reasonable way to do that is to pass a variable number of parameters and return a sequence with a matchingly variable number of type parameters.

Which brings us to dependent types :)

Today, they are important in that they bootstrap ArrayLiteralConvertible and DictionaryLiteralConvertible by (at least theoretically) acting as a pass-N-items mechanism that doesn't depend on one of the standard library types defined in terms of it. (If we convert them to show up as tuples once we have tuple subscripting syntax, that will even become true.) Less esoterically, they're used in several places where an Array would be inconvenient or break traditions:

* The `print` function's list of items to print is variadic. An array equivalent would look like `print([one, two, three])`.
* The `min` and `max` functions are more convenient than explicitly constructing an array and calling their `min()` and `max()` methods.
* And, yes, `String.init(format:_:)`, which we will probably never be quite rid of for compatibility reasons.

All those points are also perfectly solved by dependent types (which is definitely not in the time frame of Swift 3 or even Swift 4).
But I think in the long term we should get rid of varargs and Swift 3 (as far as I remember) is the last version of Swift to remove functionality from the language (is that actually correct?).

Short-term solutions:

I very very rarely use the print function with multiple parameters. Most of the time I build a single string and use string interpolation to insert values. If there really is a need for multiple arguments to print, like others said, overloads could be generated.
min and max: I think most the time they are used to compare 2 values. If there are more than 2 values (or let’s say 3) I think an array is better suited.
String.init(format:_:) … I think if all C APIs would get imported by converting varargs to arrays we could get rid of it.

--
Brent Royal-Gordon
Architechies

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

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

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

Sorry my example wasn’t clear enough, and that’s why you couldn’t tell by looking at the call site what was happening. You were missing context. "id" and "name" are not values, they’re database columns. It’s more something along:
  
  DatabaseTable {
    func select(columns: Column…) { … }
  }
  
  people.select(idColumn, nameColumn)
  furniture.select(nameColumn, widthColumn, heightColumn, depthColumn, priceColumn)

(Sometimes examples are too complex, and don't serve well their purpose - my mistake)

Maybe you’ll follow the counter argument now. Which is "of course a variadic function can always be turned into a function that takes an array, what a surprise, but this is not always the good thing to do."

Regards,
Gwendal Roué

···

Le 18 avr. 2016 à 10:02, Dennis Weissmann <dennis@dennisweissmann.me> a écrit :

That’s IMO already a problematic case:

  DatabaseTable.select(id, name).order(name, id) // What’s the problem?
  // vs.
  DatabaseTable.select([id, name]).order([name, id]) // OK, of course... But some people will find it a litle short

The problem is that you can’t tell by looking at the call site whether `select` takes an id and a name as parameter (the function being declared as `func select(id: String, _ name: String)` or a vararg `func select(string: String…)`.
Both call sites look like this:

select(id, name)

I think it would make the language clearer and more consistent if varargs were removed.

I thought that strings containing interpolation expressions did require the interpolated expression to be available in the local context. I just checked with IBM's Swift sandbox and indeed got an error when defining a string before the interpolated value, i.e.

let str = "x = \(x)"
let x = 1

Therefore I wouldn't expect strings containing interpolation expressions to work when loaded from a file (can't check that in the sandbox, though).

-Thorsten

···

Am 19.04.2016 um 18:42 schrieb Jeremy Pereira <jeremy.j.pereira@googlemail.com>:

On 19 Apr 2016, at 10:41, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Just annotenhere: String intepolation is ok for logging purposes but not for creating user messages which have to be localized (with possibly having to reorder the parameters).

Reordering is not a problem

if language == “fr"
{
   object = “me”
   verb = “lance"
}
else
{
   object = “myself”
   verb = “throw"

}

“Je \(object) \(verb) vers la gloire”
“I \(verb) \(object) towards glory"

There are other issues though (e.g. format should be in the hands of the translator) which mean I would not want to lose format strings.

-Thorsten

Am 18.04.2016 um 22:56 schrieb Dennis Weissmann via swift-evolution <swift-evolution@swift.org>:

- Dennis

On Apr 18, 2016, at 9:55 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I would like to see format strings go away and be replace with safer inline annotations.

The main problem is doing localized strings with printf-style formats well, but I actually have a pretty sweet solution for that: https://gist.github.com/brentdax/79fa038c0af0cafb52dd

-- E, somewhat agnostic on variadics

Variadics are eventually important as a generic function feature; you really want to be able to write a version of zip() which can take any number of sequences, for instance, and the only reasonable way to do that is to pass a variable number of parameters and return a sequence with a matchingly variable number of type parameters.

Which brings us to dependent types :)

Today, they are important in that they bootstrap ArrayLiteralConvertible and DictionaryLiteralConvertible by (at least theoretically) acting as a pass-N-items mechanism that doesn't depend on one of the standard library types defined in terms of it. (If we convert them to show up as tuples once we have tuple subscripting syntax, that will even become true.) Less esoterically, they're used in several places where an Array would be inconvenient or break traditions:

* The `print` function's list of items to print is variadic. An array equivalent would look like `print([one, two, three])`.
* The `min` and `max` functions are more convenient than explicitly constructing an array and calling their `min()` and `max()` methods.
* And, yes, `String.init(format:_:)`, which we will probably never be quite rid of for compatibility reasons.

All those points are also perfectly solved by dependent types (which is definitely not in the time frame of Swift 3 or even Swift 4).
But I think in the long term we should get rid of varargs and Swift 3 (as far as I remember) is the last version of Swift to remove functionality from the language (is that actually correct?).

Short-term solutions:

I very very rarely use the print function with multiple parameters. Most of the time I build a single string and use string interpolation to insert values. If there really is a need for multiple arguments to print, like others said, overloads could be generated.
min and max: I think most the time they are used to compare 2 values. If there are more than 2 values (or let’s say 3) I think an array is better suited.
String.init(format:_:) … I think if all C APIs would get imported by converting varargs to arrays we could get rid of it.

--
Brent Royal-Gordon
Architechies

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

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

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

I agree with Gwendal.

I think it is a feature that is nice to have with few drawbacks. Personally I prefer the first solution.

···

On Apr 18, 2016, at 1:10 AM, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Gwendal

Hm, sorry but I’m still not convinced :(

I still find it confusing and I think if it wasn’t in Swift already, it would not be added. Maybe someone can come up with a strong reason why it should be added if it weren’t there.

- Dennis

···

On Apr 18, 2016, at 10:10 AM, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Le 18 avr. 2016 à 10:02, Dennis Weissmann <dennis@dennisweissmann.me> a écrit :

That’s IMO already a problematic case:

  DatabaseTable.select(id, name).order(name, id) // What’s the problem?
  // vs.
  DatabaseTable.select([id, name]).order([name, id]) // OK, of course... But some people will find it a litle short

The problem is that you can’t tell by looking at the call site whether `select` takes an id and a name as parameter (the function being declared as `func select(id: String, _ name: String)` or a vararg `func select(string: String…)`.
Both call sites look like this:

select(id, name)

I think it would make the language clearer and more consistent if varargs were removed.

Sorry my example wasn’t clear enough, and that’s why you couldn’t tell by looking at the call site what was happening. You were missing context. "id" and "name" are not values, they’re database columns. It’s more something along:
  
  DatabaseTable {
    func select(columns: Column…) { … }
  }
  
  people.select(idColumn, nameColumn)
  furniture.select(nameColumn, widthColumn, heightColumn, depthColumn, priceColumn)

(Sometimes examples are too complex, and don't serve well their purpose - my mistake)

Maybe you’ll follow the counter argument now. Which is "of course a variadic function can always be turned into a function that takes an array, what a surprise, but this is not always the good thing to do."

Regards,
Gwendal Roué

Ah thanks! I forgot to select the Reply All option.

My first email:

Maybe you can check it out:

GitHub - JustinJiaDev/SwiftShell: Execute Shell Commands Inside Xcode Playground (Experimental)

I prefer to write ls(.all, .longFormat) instead of ls([.all, .longFormat]). The former one looks a lot nicer. And it is much easier to type. This is important if I want to use it as a shell.

Dennis's reply:

Hey Justin, you didn’t include the list, if you want to keep your mail private: perfect, if not: now you know it :)

Regarding your example:

I think that’s a pretty good use case for an OptionSetType (which, unfortunately for you, leads to the same syntax you dislike [without the dot in front of the identifier]).
And remember that you can still overload the functions (having different numbers of arguments) :)

- Dennis

I didn't realize that I can use OptionalSetType. Thanks for pointing it out! But I chose to use enum is because of the auto completion. I can see the list of options after I enter the leading dot.

It's a experimental project. But my point is: Swift is very safe and efficient, but at the same time it is also very flexible. Removing this feature will harm its flexibility.

I agree that we should remove the splat behavior, c style for loop and ++ -- operators, because sometimes they will confuse people.

e.g.

array[index++] = x;
array[++index] = x;

However, variadic functions are really easy to understand.

For example:

sum(x)
average(x)
NSLog("%d", x)
NSString.stringWithFormat("%d", x)

Justin

···

On Apr 18, 2016, at 2:13 PM, Dennis Weissmann <dennis@dennisweissmann.me> wrote:

Hey Justin, you didn’t include the list, if you want to keep your mail private: perfect, if not: now you know it :)

Regarding your example:

I think that’s a pretty good use case for an OptionSetType (which, unfortunately for you, leads to the same syntax you dislike [without the dot in front of the identifier]).
And remember that you can still overload the functions (having different numbers of arguments) :)

- Dennis

On Apr 18, 2016, at 11:03 PM, Justin Jia <justin.jia.developer@gmail.com> wrote:

Maybe you can check it out:

GitHub - JustinJiaDev/SwiftShell: Execute Shell Commands Inside Xcode Playground (Experimental)

I prefer to write ls(.all, .longFormat) instead of ls([.all, .longFormat]). The former one looks a lot nicer. And it is much easier to type. This is important if I want to use it as a shell.

Justin

On Apr 18, 2016, at 5:55 AM, Dennis Weissmann <dennis@dennisweissmann.me> wrote:

Hm, sorry but I’m still not convinced :(

I still find it confusing and I think if it wasn’t in Swift already, it would not be added. Maybe someone can come up with a strong reason why it should be added if it weren’t there.

- Dennis

On Apr 18, 2016, at 10:10 AM, Gwendal Roué <gwendal.roue@gmail.com> wrote:

Le 18 avr. 2016 à 10:02, Dennis Weissmann <dennis@dennisweissmann.me> a écrit :

That’s IMO already a problematic case:

  DatabaseTable.select(id, name).order(name, id) // What’s the problem?
  // vs.
  DatabaseTable.select([id, name]).order([name, id]) // OK, of course... But some people will find it a litle short

The problem is that you can’t tell by looking at the call site whether `select` takes an id and a name as parameter (the function being declared as `func select(id: String, _ name: String)` or a vararg `func select(string: String…)`.
Both call sites look like this:

select(id, name)

I think it would make the language clearer and more consistent if varargs were removed.

Sorry my example wasn’t clear enough, and that’s why you couldn’t tell by looking at the call site what was happening. You were missing context. "id" and "name" are not values, they’re database columns. It’s more something along:
  
  DatabaseTable {
    func select(columns: Column…) { … }
  }
  
  people.select(idColumn, nameColumn)
  furniture.select(nameColumn, widthColumn, heightColumn, depthColumn, priceColumn)

(Sometimes examples are too complex, and don't serve well their purpose - my mistake)

Maybe you’ll follow the counter argument now. Which is "of course a variadic function can always be turned into a function that takes an array, what a surprise, but this is not always the good thing to do."

Regards,
Gwendal Roué

+1 to remove them(vararg) or introduce special marker for variadic params.

IMO: I think variadic parameters is alien construction in Swift, where we expect that the method call explicitly tells us what is the purpose of each parameter by using external param names.

Plus, variadic parameters are actually array of values. We don't like if something is implicit in Swift. If we pass an array of values, why we allows this without specifying array's explicity.
Or, why there is no explicit marker for such method that it has variadic parameters(don't know, something like .select(:id, name)). Probably this will be an OK solution also - to have special marker for variadic parameters.

Yes, I expect to see .select(id, withName: name). Construction like .select(id, name) seems like incorrectly defined method(w/o external name for second parameter).

Btw, for those who like variadic parameters: Do you support that Swift 3.0 will not allow a tuple instead of prarameters for methods?

This feature also was used and probably can be handful in some situations. But, one of the main reasons why it was(will be) removed (Quote):
* A call to foo(x) looks like a call to an overloaded version of foo, both to the compiler and to the human who maintains the code. This is extremely confusing if you don't know the feature exists.
*(?) The current implementation adds complexity to the type checker, slowing it down and adding maintenance burden.

···

On 18.04.2016 15:55, Dennis Weissmann via swift-evolution wrote:
> Hm, sorry but I’m still not convinced :(
>
> I still find it confusing and I think if it wasn’t in Swift already, it
> would not be added. Maybe someone can come up with a strong reason why it
> should be added if it weren’t there.
>
> - Dennis
>
>> On Apr 18, 2016, at 10:10 AM, Gwendal Roué <gwendal.roue@gmail.com >> <mailto:gwendal.roue@gmail.com>> wrote:
>>
>>> Le 18 avr. 2016 à 10:02, Dennis Weissmann <dennis@dennisweissmann.me >>> <mailto:dennis@dennisweissmann.me>> a écrit :
>>>
>>> That’s IMO already a problematic case:
>>>
>>>> DatabaseTable.select(id, name).order(name, id)// What’s the problem?
>>>> // vs.
>>>> DatabaseTable.select([id, name]).order([name, id])// OK, of course...
>>>> But some people will find it a litle short
>>>
>>> The problem is that you can’t tell by looking at the call site whether
>>> `select` takes an id and a name as parameter (the function being
>>> declared as `func select(id: String, _ name: String)` or a vararg `func
>>> select(string: String…)`.
>>> Both call sites look like this:
>>>
>>>> select(id, name)
>>>
>>> I think it would make the language clearer and more consistent if
>>> varargs were removed.
>>
>> Sorry my example wasn’t clear enough, and that’s why you couldn’t tell by
>> looking at the call site what was happening. You were missing context.
>> "id" and "name" are not values, they’re database columns. It’s more
>> something along:
>>
>> DatabaseTable {
>> func select(columns: Column…) { … }
>> }
>>
>> people.select(idColumn, nameColumn)
>> furniture.select(nameColumn, widthColumn, heightColumn, depthColumn,
>> priceColumn)
>>
>> (Sometimes examples are too complex, and don't serve well their purpose -
>> my mistake)
>>
>> Maybe you’ll follow the counter argument now. Which is "of course a
>> variadic function can always be turned into a function that takes an
>> array, what a surprise, but this is not always the good thing to do."
>>
>> Regards,
>> Gwendal Roué
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

  NSString.stringWithFormat(“%d”, x)
  NSString.stringWithFormat(“%d”, )

The second format is a tiny bit longer, but more explicit at the call-site about what is going on, whereas the first, if you don’t know the function, is indistinguishable from a function that takes a single argument of whatever type x is.

I’m kind of in the remove variadic functions camp as a result, as I’d prefer to be more explicit about the type rather than less, and it’s not as if two square brackets is going to kill anyone. The main issue for me is whether there are ways for variadic functions to be optimised that aren’t available to a full-blown array? I don’t know enough about the compiler side to comment on that, but it seems like maybe there could be an optimisation for variadic argument lists.

The other question is how would we implement ArrayLiteralConvertible (and DictionaryLiteralConvertible) without variadic functions? As if the aim is to instantiate an array alternative without having to have a full array instance first then variadic functions may be able to allow this? Again I’m not certain on that point.

···

On 19 Apr 2016, at 00:14, Justin Jia via swift-evolution <swift-evolution@swift.org> wrote:
variadic functions are really easy to understand.

For example:

sum(x)
average(x)
NSLog("%d", x)
NSString.stringWithFormat("%d", x)

No, that’s not the question. The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature. Whereas, if you remove the feature, those people of the opinion “it makes code a tiny bit more readable” have nowhere to go.

···

On 19 Apr 2016, at 07:51, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

+1

As I said, we have been using NSLog and StringWithFormat: for many years, and I think most people don't have any difficulty understanding how a variadic function work.

If we removed this feature, existing APIs would break. I don't think we should be afraid of breaking old code. However, no one convinced me that variadic functions are as bad as ++ operators that worth removing it.

Justin

···

On Apr 19, 2016, at 9:34 AM, Jeremy Pereira <jeremy.j.pereira@googlemail.com> wrote:

On 19 Apr 2016, at 07:51, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

No, that’s not the question. The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature. Whereas, if you remove the feature, those people of the opinion “it makes code a tiny bit more readable” have nowhere to go.

+1000 to that sentence.

Gwendal Roué

···

Le 19 avr. 2016 à 18:34, Jeremy Pereira via swift-evolution <swift-evolution@swift.org> a écrit :

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo

I suggest to look at the subject of this thread and initial proposal:
"Swift should allow passing an *array to variadic functions*, or we should implement a type-safe `apply()` function in the standard library."

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

For example we have:
func foo(x: Int ...) {..}

and later in code we have
var arr : [Int] = getSomehow()

Should we be able to call foo in this way:

foo(arr)

Or how we can call foo(..) about array of values, not values as list of parameters.

···

On 19.04.2016 19:34, Jeremy Pereira via swift-evolution wrote:

On 19 Apr 2016, at 07:51, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

No, that’s not the question. The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature. Whereas, if you remove the feature, those people of the opinion “it makes code a tiny bit more readable” have nowhere to go.

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

The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature.

Afaics, this isn't true:
Increment/decrement operators, currying, tuple splat and even the C-style for loop have already been deprecated, and although I would have preferred to keep some of those constructs, I think it is good how progressive Swift is pushed forward ("would we add this feature now if it wasn't already there?").

The value of variadic functions is imho less than the possibility to omit "()" in procedure calls, and afair, there have been several posts that illustrate the complications of this feature.

Pros of removing variadic functions:
1. Slightly easier to understand.
2. Simpler language design.

Cons of removing variadic functions:
1. More verbose syntax.
2. Break old code.

I understand your reasons. But,

1. People have been using NSLog and StringWithFormat for many years and most people don't have any difficulty understanding them. So the benefit of removing this feature is very subtle.
2. The solution I proposed to fix is very straightforward. I don't think it will too much cost. (Maybe we need someone who is familiar with compiler to compare the cost).

Also,

1. Sometimes we need simpler syntax. Like this project: GitHub - JustinJiaDev/SwiftShell: Execute Shell Commands Inside Xcode Playground (Experimental)
I prefer to write ls(.all, .longFormat) instead of ls([.all, .longFormat]). That's really important if we want to use it as a shell.
2. It not only breaks the language itself, it will also break cocoa APIs. That is bad.

Justin

···

On Apr 19, 2016, at 10:54 AM, Haravikk <swift-evolution@haravikk.me> wrote:

On 19 Apr 2016, at 17:51, Vladimir.S <svabox@gmail.com> wrote:

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

I’d say it’s on-topic, as removing variadic functions would eliminate the problem entirely, so if it is considered a better alternative then there would be no need to have an additional means of calling them with an array of arguments.

Personally the way I see it comes down to variadic functions is this:

Pros:
Slightly cleaner syntax at call-site.
Possibly optimisations unavailable to Array passing?

Cons:
Doesn’t do anything that passing an array directly can’t.
Passing an array is actually slightly more flexible (can dynamically pass more or less arguments as required at the call site).
Less explicit type at call site; gives the appearance of passing instance(s) of Foo, rather than one instance of [Foo], can lead to ambiguity with overloaded functions.
Extra syntax to support (enabling array passing would be more code required to support this feature)

I’d also argue that variadic functions increase the learning curve, as the first time you’re presented with one it isn’t necessarily clear what it does unless you’ve encountered them before. Like I say it can be ambiguous at the call-site in particular, as it doesn’t show that an array of [Foo] is being passed as opposed to N instances of Foo (however many are in the call).

While I’ve used them in the past, I’ve never really felt that they simplify anything enough to justify them, as it’s just two square brackets extra to pass an array; this is extra noise sure, but clarifies what is actually happening.

So if variadic functions don’t have any other advantages, then it’s really just a very minor piece of syntactic sugar that can lead to more confusion, less explicit types in function calls, an extra piece of syntax to parse and handle and possibly other features required to support it better (like the one being inquired about). The only other argument I can think of for them is that many other languages have them, but that’s not important to me vs cutting out cruft.

Short version; removing variadic functions would solve the problem of defining overloads for both variadic and array types by only ever requiring the latter.

P.S- I’d also like to note that where possible people should be accepting Sequences or Collections in their methods anyway rather than arrays specifically, as it’s more flexible that way ;)

I’d say it’s on-topic, as removing variadic functions would eliminate the problem entirely, so if it is considered a better alternative then there would be no need to have an additional means of calling them with an array of arguments.

Personally the way I see it comes down to variadic functions is this:

Pros:
Slightly cleaner syntax at call-site.
Possibly optimisations unavailable to Array passing?

Cons:
Doesn’t do anything that passing an array directly can’t.
Passing an array is actually slightly more flexible (can dynamically pass more or less arguments as required at the call site).
Less explicit type at call site; gives the appearance of passing instance(s) of Foo, rather than one instance of [Foo], can lead to ambiguity with overloaded functions.
Extra syntax to support (enabling array passing would be more code required to support this feature)

I’d also argue that variadic functions increase the learning curve, as the first time you’re presented with one it isn’t necessarily clear what it does unless you’ve encountered them before. Like I say it can be ambiguous at the call-site in particular, as it doesn’t show that an array of [Foo] is being passed as opposed to N instances of Foo (however many are in the call).

While I’ve used them in the past, I’ve never really felt that they simplify anything enough to justify them, as it’s just two square brackets extra to pass an array; this is extra noise sure, but clarifies what is actually happening.

So if variadic functions don’t have any other advantages, then it’s really just a very minor piece of syntactic sugar that can lead to more confusion, less explicit types in function calls, an extra piece of syntax to parse and handle and possibly other features required to support it better (like the one being inquired about). The only other argument I can think of for them is that many other languages have them, but that’s not important to me vs cutting out cruft.

Short version; removing variadic functions would solve the problem of defining overloads for both variadic and array types by only ever requiring the latter.

P.S- I’d also like to note that where possible people should be accepting Sequences or Collections in their methods anyway rather than arrays specifically, as it’s more flexible that way ;)

···

On 19 Apr 2016, at 17:51, Vladimir.S <svabox@gmail.com> wrote:

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

Would that require some compiler magic, i.e.

foo(#splat(arr))

···

On Apr 19, 2016, at 12:51 PM, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

I suggest to look at the subject of this thread and initial proposal:
"Swift should allow passing an *array to variadic functions*, or we should implement a type-safe `apply()` function in the standard library."

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

For example we have:
func foo(x: Int ...) {..}

and later in code we have
var arr : [Int] = getSomehow()

Should we be able to call foo in this way:

foo(arr)

Or how we can call foo(..) about array of values, not values as list of parameters.

On 19.04.2016 19:34, Jeremy Pereira via swift-evolution wrote:

On 19 Apr 2016, at 07:51, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

No, that’s not the question. The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature. Whereas, if you remove the feature, those people of the opinion “it makes code a tiny bit more readable” have nowhere to go.

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

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

Cons of removing variadic functions:
1. More verbose syntax.
2. Break old code.

The verbosity is only two characters (square brackets), and it needn’t break old code:

  Before: func myFunc(values:Foo…)
  After: func myFunc(values:[Foo])

  Before: myFunc(foo, bar, baz)
  After: myFunc([foo, bar, baz])

Currently variadic functions just produce an array of arguments anyway, so simply translating call-sites to pass in an array guarantees compatibility.

···

On 19 Apr 2016, at 20:25, Justin Jia <justin.jia.developer@gmail.com> wrote:

On Apr 19, 2016, at 10:54 AM, Haravikk <swift-evolution@haravikk.me <mailto:swift-evolution@haravikk.me>> wrote:

On 19 Apr 2016, at 17:51, Vladimir.S <svabox@gmail.com <mailto:svabox@gmail.com>> wrote:

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

I’d say it’s on-topic, as removing variadic functions would eliminate the problem entirely, so if it is considered a better alternative then there would be no need to have an additional means of calling them with an array of arguments.

Personally the way I see it comes down to variadic functions is this:

Pros:
Slightly cleaner syntax at call-site.
Possibly optimisations unavailable to Array passing?

Cons:
Doesn’t do anything that passing an array directly can’t.
Passing an array is actually slightly more flexible (can dynamically pass more or less arguments as required at the call site).
Less explicit type at call site; gives the appearance of passing instance(s) of Foo, rather than one instance of [Foo], can lead to ambiguity with overloaded functions.
Extra syntax to support (enabling array passing would be more code required to support this feature)

I’d also argue that variadic functions increase the learning curve, as the first time you’re presented with one it isn’t necessarily clear what it does unless you’ve encountered them before. Like I say it can be ambiguous at the call-site in particular, as it doesn’t show that an array of [Foo] is being passed as opposed to N instances of Foo (however many are in the call).

While I’ve used them in the past, I’ve never really felt that they simplify anything enough to justify them, as it’s just two square brackets extra to pass an array; this is extra noise sure, but clarifies what is actually happening.

So if variadic functions don’t have any other advantages, then it’s really just a very minor piece of syntactic sugar that can lead to more confusion, less explicit types in function calls, an extra piece of syntax to parse and handle and possibly other features required to support it better (like the one being inquired about). The only other argument I can think of for them is that many other languages have them, but that’s not important to me vs cutting out cruft.

Short version; removing variadic functions would solve the problem of defining overloads for both variadic and array types by only ever requiring the latter.

P.S- I’d also like to note that where possible people should be accepting Sequences or Collections in their methods anyway rather than arrays specifically, as it’s more flexible that way ;)

Would that require some compiler magic, i.e.

>
> foo(#splat(arr))

Probably yes. Although passing array to variadic func IMO is must-have feature, I don't think it will be used very often, so using of such compiler magic seems OK at the moment when we need this.

Also this solves the problem that passing array to variadic func is confusing about the arguments of function. If just pass array to such function - it is not clear what parameters of the function, is it variadic or "usual" function, is array just first argument or each value in array is argument.

The #splat solution is explicit, clearly mark function as variadic and array as a collection of parameters, it is *obvious* what is going there.

And as it is compiler business(at the compilation time) to interpret "arr" as a source of arguments for function - I think #splat is a correct solution.

To @Justin: I suggest to include this solution to the proposal.

···

On 20.04.2016 2:07, Ricardo Parada wrote:

On Apr 19, 2016, at 12:51 PM, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

I suggest to look at the subject of this thread and initial proposal:
"Swift should allow passing an *array to variadic functions*, or we should implement a type-safe `apply()` function in the standard library."

I.e. the question is *if we want/need to be able to pass array to existed variadic function*. Not about removing the variadic feature("removing" is offtop for this poposal, as I understand)

For example we have:
func foo(x: Int ...) {..}

and later in code we have
var arr : [Int] = getSomehow()

Should we be able to call foo in this way:

foo(arr)

Or how we can call foo(..) about array of values, not values as list of parameters.

On 19.04.2016 19:34, Jeremy Pereira via swift-evolution wrote:

On 19 Apr 2016, at 07:51, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

I think the question really is whether not having to add square brackets is really enough to justify a whole language feature? Basically you’ve got two ways you could do this:

No, that’s not the question. The question is whether the downside to variadic parameters is really enough to justify _removing_ an existing language feature.

The burden of justification should be on those people wanting to change the language, not on those wanting to maintain the status quo and “I don’t like it” or “I think it makes code a tiny bit less readable” is not sufficient justification, in my opinion because you already have the option not to use the feature. Whereas, if you remove the feature, those people of the opinion “it makes code a tiny bit more readable” have nowhere to go.

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

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

At this moment I think we should keep "variadic" feature just because it is very handy and useful practically, in our day-by-day coding. Without it we'll have to write a number of overloaded functions or use all the time.
I.e. I believe nobody wants to write
print([i])
print(["hello"])
print([i,j])
, and for this we'll need declarations
print(:)
print(::)
print(:::)
..
print()

Plus, array of values is not the same as a list of parameters at the end. Using of array instead of parameters probably confuses more than variadic parameters for the same function name.

So, the cons of having variadic functions are much less than the pros.

But +1 to be able to use array as parameters by using some #splat compiler-time func, i.e. print(#splat(arr)) - explicit and clear

···

On 19.04.2016 22:25, Justin Jia wrote:

Pros of removing variadic functions:
1. Slightly easier to understand.
2. Simpler language design.

Cons of removing variadic functions:
1. More verbose syntax.
2. Break old code.

I understand your reasons. But,

1. People have been using NSLog and StringWithFormat for many years and
most people don't have any difficulty understanding them. So the benefit of
removing this feature is very subtle.
2. The solution I proposed to fix is very straightforward. I don't think it
will too much cost. (Maybe we need someone who is familiar with compiler to
compare the cost).

Also,

1. Sometimes we need simpler syntax. Like this project:
GitHub - JustinJiaDev/SwiftShell: Execute Shell Commands Inside Xcode Playground (Experimental)
I prefer to write ls(.all, .longFormat) instead of ls([.all, .longFormat]).
That's really important if we want to use it as a shell.
2. It not only breaks the language itself, it will also break cocoa APIs.
That is bad.

Justin

On Apr 19, 2016, at 10:54 AM, Haravikk <swift-evolution@haravikk.me > <mailto:swift-evolution@haravikk.me>> wrote:

On 19 Apr 2016, at 17:51, Vladimir.S <svabox@gmail.com >>> <mailto:svabox@gmail.com>> wrote:

I.e. the question is *if we want/need to be able to pass array to
existed variadic function*. Not about removing the variadic
feature("removing" is offtop for this poposal, as I understand)

I’d say it’s on-topic, as removing variadic functions would eliminate the
problem entirely, so if it is considered a better alternative then there
would be no need to have an additional means of calling them with an
array of arguments.

Personally the way I see it comes down to variadic functions is this:

*Pros*:

  * Slightly cleaner syntax at call-site.
  * Possibly optimisations unavailable to Array passing?

*Cons*:

  * Doesn’t do anything that passing an array directly can’t.
  * Passing an array is actually slightly more flexible (can dynamically
    pass more or less arguments as required at the call site).
  * Less explicit type at call site; gives the appearance of passing
    instance(s) of Foo, rather than one instance of [Foo], can lead to
    ambiguity with overloaded functions.
  * Extra syntax to support (enabling array passing would be more code
    required to support this feature)

I’d also argue that variadic functions increase the learning curve, as
the first time you’re presented with one it isn’t necessarily clear what
it does unless you’ve encountered them before. Like I say it can be
ambiguous at the call-site in particular, as it doesn’t show that an
array of [Foo] is being passed as opposed to N instances of Foo (however
many are in the call).

While I’ve used them in the past, I’ve never really felt that they
simplify anything enough to justify them, as it’s just two square
brackets extra to pass an array; this is extra noise sure, but clarifies
what is actually happening.

So if variadic functions don’t have any other advantages, then it’s
really just a very minor piece of syntactic sugar that can lead to more
confusion, less explicit types in function calls, an extra piece of
syntax to parse and handle and possibly other features required to
support it better (like the one being inquired about). The only other
argument I can think of for them is that many other languages have them,
but that’s not important to me vs cutting out cruft.

Short version; removing variadic functions would solve the problem of
defining overloads for both variadic and array types by only ever
requiring the latter.

P.S- I’d also like to note that where possible people should be accepting
Sequences or Collections in their methods anyway rather than arrays
specifically, as it’s more flexible that way ;)