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

Gwendal Roué gwendal.roue at gmail.com
Fri Jun 9 02:12:24 CDT 2017


>>     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:

    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
    notOverloaded2 { x, y in x + y }   // Swift 4 error
    notOverloaded2 { (x, y) in x + y } // Swift 4 error
    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.

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/171ac351/attachment.html>


More information about the swift-evolution mailing list