[swift-evolution] Proposal: Always flatten the single element tuple

Mark Lacey mark.lacey at apple.com
Fri Jun 9 02:41:26 CDT 2017


> On Jun 9, 2017, at 12:12 AM, Gwendal Roué <gwendal.roue at gmail.com> wrote:
> 
>>>     func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return "notOverloaded1" }
>>>     func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { return "notOverloaded3" }
>>>     
>>>     func overloaded(_ closure: (Int, Int) -> Int) -> String { return "overloaded 1" }
>>>     func overloaded(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { return "overloaded 2" }
>>>     
>>>     // not overloaded => not ambiguous
>>>     notOverloaded1 { x, y in x + y }
>>>     notOverloaded1 { (x, y) in x + y }
>>>     notOverloaded1 { _ in 1 }
>>>     notOverloaded2 { x, y in x + y }
>>>     notOverloaded2 { (x, y) in x + y }
>>>     notOverloaded2 { _ in 1 }
>>>     
>>>     // overloaded => resolve ambiguity on closure argument, when possible
>>>     overloaded { x, y in x + y }        // "overloaded 1"
>>>     overloaded { (x, y) in x + y }      // "overloaded 1"
>>>     overloaded { t in t.lhs + t.rhs }   // "overloaded 2"
>>>     overloaded { (t) in t.lhs + t.rhs } // "overloaded 2”
>> 
>> This is exactly what happens today as a result of SE-0110 since the first two calls take two arguments, and the next two take a single argument.
> 
> No, as a playground quickly reveals:

I was specifically referring to the last four statements but could have made that more clear.

>     func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return "notOverloaded1" }
>     func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { return "notOverloaded3" }
>     
>     // not overloaded => not ambiguous
>     notOverloaded1 { x, y in x + y }
>     notOverloaded1 { (x, y) in x + y }
>     notOverloaded1 { _ in 1 }          // Swift 4 error

This really should be an error. It’s one thing to say that { x, y in } should work as it used to in the case where a closure taking a tuple is expected, but something else entirely to say that _ should work in any case, regardless of whether a closure taking N arguments or a closure taking an N-tuple is expected for any N. I can see a desire to make _ work for any tuple, and _, _ work for a two-tuple based on context if e.g. “x, y in” also works, but not for _ working where a closure requiring N independent arguments is expected.

>     notOverloaded2 { x, y in x + y }   // Swift 4 error
>     notOverloaded2 { (x, y) in x + y } // Swift 4 error

In these cases using the tuple labels works as well (as it does in your examples where the overloaded function is involved). I’m not arguing that it’s as good as being able to do the apparent destructuring, but just want to point out that it works. I didn’t get the sense from your email that you found that objectionable in the cases involving overloads, but perhaps you do.

>     notOverloaded2 { _ in 1 }
> 
> Those errors are the famous regressions we want to fix.
> 
>>>     overloaded { _ in 1 }               // error: ambiguous use of ‘overloaded'
>> 
>> With SE-0110 in its current form, this calls the tuple version since there is a single closure parameter listed.
> 
> It would be nicer if. { _ in ... } would always mean "I don't care". With an ambiguity in the sample code we're looking at, and a compiler error.

How does making something that is unambiguous today actually be ambiguous improve things?

Mark

> The { (_, _) in ... } form is arguably cluttered, and it would be nicer it is was required only for disambiguition.
> 
>>>     overloaded { (_) in 1 }             // "overloaded 1”
>> 
>> With SE-0110 in its current form, this calls the tuple version since there is a single closure parameter listed. I don’t understand why you would suggest this should call the two-argument version since that’s inconsistent with the other closures above that have a single argument.
>> 
>>>     overloaded { (_, _) in 1 }          // "overloaded 2”
>> 
>> With SE-0110 in its current form, this calls the two-argument version since there are two listed arguments.
> 
> I was wrong, sorry. I meant what you replied.
> 
> Gwendal
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170609/7b72cca0/attachment.html>


More information about the swift-evolution mailing list