> On 8 Jun 2017, at 11:17, Gwendal Roué via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> Le 8 juin 2017 à 19:40, Brent Royal-Gordon via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>> 
>>> On Jun 7, 2017, at 3:03 AM, Adrian Zubarev via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Well please no:
>>> 
>>> 
>>>  let fn2: ((Int, Int)) -> Void = { lhs, rhs in } 
>>> 
>>> Instead use destructuring sugar pitched by Chris Lattner on the other 
>>> thread:
>>> 
>>> let fn2: ((Int, Int)) -> Void = { ((lhs, rhs)) in }
>>> 
>> 
>> I think this suggestion is better than the status quo. I'm wondering, 
>> though, if we should just drop the outer set of parentheses entirely, unless 
>> you're also putting types on the parameters. That is, a closure of type 
>> `(Int, Int) -> T` can look like this:
>> 
>>      { (x: Int, y: Int) in … }
>> 
>> Or it can look like this:
>> 
>>      { x, y in … }
>> 
>> But it *cannot* look like this:
>> 
>>      { (x, y) in … }
>> 
>> The `(x, y)` form can instead be a closure of a type like `((Int, Int)) -> 
>> T`, which immediately destructures the tuple parameter into separate 
>> constants.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
> 
> Hello,
> 
> There's a difference, in the mind of people here that try to show how bad 
> were the recent changes, between:
> 
> 1: closures defined independently
> 2: closures given as a parameter to a function.
> 
> I think that we all agree that the type of a closure that is defined 
> independently should be well defined:
> 
>     // Choose between (Int, Int) -> () or ((x: Int, y: Int)) -> ()
>     let a = { (x: Int, y: Int) -> Int in ... }
>     let b = { ((x: Int, y: Int)) -> Int in ... }
> 
> However, when a closure is given as an argument of a function that expects a 
> closure, we ask for the maximum possible flexibility, as Swift 3 did:
> 
>     func wantsTwoArguments(_ closure: (Int, Int) -> Int) { closure(1, 2) }
>     wantsTwoArguments { a, b in a + b }
>     wantsTwoArguments { (a, b) in a + b }
>     wantsTwoArguments { t in t.0 + t.1 } // OK, maybe not
> 
>     func wantsATupleArgument(_ closure: ((Int, Int)) -> Int) { closure((1, 
> 2)) }
>     wantsATupleArgument { a, b in a + b }
>     wantsATupleArgument { (a, b) in a + b }
>     wantsATupleArgument { t in t.0 + t.1 }
>     
>     func wantsANamedTupleArgument(_ closure: ((lhs: Int, rhs: Int)) -> Int) { 
> closure((lhs: 1, rhs: 2)) }
>     wantsANamedTupleArgument { a, b in a + b }
>     wantsANamedTupleArgument { (a, b) in a + b }
>     wantsANamedTupleArgument { t in t.lhs + t.rhs }
> 
> This gives us the ability to deal with unfitted function signatures. For 
> example, most Dictionary methods. Yes, they are usually unfitted:
> 
>     extension Dictionary {
>         func forEach(_ body: ((key: Key, value: Value)) throws -> Void) 
> rethrows
>     }
> 
> Who cares about this named (key:value:) tuple? Absolutely nobody, as 
> exemplified by this remarquable Swift 3 snippet below, where no tuple, no 
> `key`, and no `value` is in sight:
> 
>     let scores: [String: Int] = ... // [playerName: score]
>     scores.forEach { name, score in
>         print("\(name): \(score)")
>     }
> 
> Do you see?

This post is the one that makes most sense to me! Be strict on definition but 
flexible on use.

> Gwendal
> 
> 
> _______________________________________________
> 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

Reply via email to