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

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


> Le 9 juin 2017 à 09:41, Mark Lacey <mark.lacey at apple.com> a écrit :
> 
> 
>> On Jun 9, 2017, at 12:12 AM, Gwendal Roué <gwendal.roue at gmail.com <mailto: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.

I argue this is a subjective statement, and my own subjective statement is that it should not to be an error. So that { _ in ... } would always mean "I don't care".

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

Yes. That's why it's subjective. You argue that you don't like it, not that it's impossible to do. Because you can't prove it's impossible to do. Because I have shown that it is. In a nice manner that is easy to developers.

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

I *do* suggest a specific handling of { _ ... }. I have shown how it can be implemented in a non-ambiguous fashion. Please don't act as if I did not.

Now the specific case of { _ ... } is interesting, but I wouldn't make it as important as the other regressions.

I should make an exhaustive compilation of Swift 4 regressions, so that you opponents can see how *far* things have changed, fixing a few corner cases, and breaking tons of valid code. At least we could discuss each case in isolation.

Gwendal

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


More information about the swift-evolution mailing list