[swift-evolution] Revisiting SE-0110

Vladimir.S svabox at gmail.com
Mon May 29 13:42:31 CDT 2017


On 29.05.2017 21:07, Robert Bennett wrote:
> The word you're looking for is inconvenient 😁
> 
> If we allow dropping parentheses for tuples then we should disallow the outer
> parentheses to avoid ambiguity between multi-argument closures and closures taking
> a single tuple as their argument. Then, a closure taking multiple arguments would
> have to be written as "x, y in" and a closure taking a tuple as "(x, y) in". I'm
> ok with this too. I just want to make sure whatever solution we come up with
> adheres to the goal of SE-0110, which is to clearly separate functions taking
> multiple arguments from functions taking a tuple. For clarity, whatever solution
> we come up with should wrap the arguments within a tuple in an extra pair of
> parentheses. So for a multi-argument and single-tuple closure, respectively,
> either "x, y in" and "(x, y) in", or "(x, y) in" and "((x, y)) in".

Well, from my point of view closure deserves some special syntax and rules. And IMO
it is important to support currently allowed syntax of {x,y in} == {(x,y) in ..} to 
reduce the code breaking changes and to keep simple clear syntax in most situations.

But we should resolve the ambiguity related to tuple splatting/deconstructing in 
arguments of closure. Two ways: disallow this feature or introduce separate syntax.

So, the only *correct* way I see - is use of ((x,y)) for deconstructing tuple argument.

In this case, when close with single tuple argument(say of type (Int,Int)) is 
required, we can write this:
{tuple in ...}
{(tuple) in ...}
{((x,y)) in ...} // tuple deconstruction into x and y variables
//{(x,y) in ...} // should be disallowed

the ((x,y)) syntax follows the way of SE-0066's type of function with single tuple 
argument:"...
(Int, Int) -> Int    // function from Int and Int to Int
((Int, Int)) -> Int  // function from tuple (Int, Int) to Int
..."

Again, please note that SE-0110 is based on previous accepted proposals: SE-0066 and 
SE-0029.

> 
>> On May 29, 2017, at 1:32 PM, Vladimir.S via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> 
>>> On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote: On
>>> Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution
>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote: We need
>>> to add back tuple destructuring in closure parameter lists because this is a
>>> serious usability regression.  If we're reluctant to just "do the right thing"
>>> to handle the ambiguity of (a,b), we should at least allow it via unambiguous
>>> syntax like ((a,b)).  I do think that we should just "do the right thing",
>>> however, with my biggest concern being whether there's any reasonable way to
>>> achieve that in 4.0. John. I agree with John, the best thing for actually
>>> using Swift is to allow tuple destructuring here, and the outermost
>>> parentheses (around the entire parameter list of a closure) should continue to
>>> be optional. Requiring double-parens would seem unnecessarily and
>>> arbitrarily…whatever the opposite of “convenient” is. Nevin
>> 
>> If I understand correctly, correct me if I'm wrong, after *full* implementation
>> of SE-0066, the function with two parameters should have different type than
>> function with one tuple parameter:
>> 
>> I.e. typealias FuncParams = (Int, Int)->() typealias FuncTuple = ((Int,
>> Int))->()
>> 
>> print(FuncParams.self) // should be (Int, Int)->() print(FuncTuple.self) //
>> should be ((Int, Int))->()
>> 
>> So, if we have
>> 
>> func barParams(_ f: FuncParams) { f(1,2) }
>> 
>> func barTuple(_ f: FuncTuple) { f((1,2)) }
>> 
>> and
>> 
>> func fooWithParams(_ x: Int,  _ y: Int) {  } func fooWithTuple(_ tuple: (Int,
>> Int)) {  }
>> 
>> .. we should not be able to call
>> 
>> barParams(fooWithTuple) // should be error: incompatible types 
>> barTuple(fooWithParams) // should be error: incompatible types
>> 
>> 
>> If so, are you suggesting that this code should still be valid?
>> 
>> barParams({tuple in}) // ? barTuple({x,y in}) // ?
>> 
>> 
>> Will {x,y in} closure has ((Int, Int))->() type in this case? And if {tuple in}
>> should be of type (Int,Int)->() ?
>> 
>> If I'm not missing something, the only reasonable solution here is follow the
>> SE-0066 rules for function types and allow special syntax ((x,y)) to deconstruct
>> tuple parts in closure argument list, and such closure will have type
>> ((Int,Int))->() as expected. So we'll have:
>> 
>> barTuple({((x,y)) in ... })
>> 
>> 
>>> _______________________________________________ swift-evolution mailing list 
>>> swift-evolution at swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________ swift-evolution mailing list 
>> swift-evolution at swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 


More information about the swift-evolution mailing list