[swift-evolution] Revisiting SE-0110

Nevin Brackett-Rozinsky nevin.brackettrozinsky at gmail.com
Mon May 29 13:08:49 CDT 2017


Vladimir, using your function definitions I would like to have:

// Two parameters:
barParams{ t in }       // invalid, too few parameters
barParams{ (t) in }     // invalid, too few parameters
barParams{ x, y in }    // valid, two parameters
barParams{ (x, y) in }  // valid, two parameters with optional parentheses
barParams{ ((x, y)) in }// invalid, too few parameters

// One parameter which is a 2-tuple:
barTuple{ t in }        // valid, one tuple parameter
barTuple{ (t) in }      // valid, one tuple parameter with optional
parentheses
barTuple{ x, y in }     // invalid, too many parameters
barTuple{ (x, y) in }   // valid, destructuring one tuple
barTuple{ ((x, y)) in } // valid, destructuring one tuple with optional
parentheses

For completeness: if a closure takes *any number* of parameters, it should
be legal to list one identifier per parameter, separated by commas, with
optionally a pair of parentheses surrounding that list. Furthermore, if
*any* parameter is a tuple, it should be possible to replace the identifier
corresponding to that parameter with a pair of parentheses containing a
number of identifiers (separated by commas) equal to the arity of the
tuple. And this tuple-destructuring should work recursively, so if a tuple
contains a tuple [contains a tuple…] the inner tuples may optionally be
destructured as well.

To be clear: each tuple being destructured must have a pair of parentheses
containing the identifiers it is being destructured into. It is only the
very outermost parentheses around the entire parameter list of the closure
which should be optional.

Nevin



On Mon, May 29, 2017 at 1:32 PM, Vladimir.S <svabox at gmail.com> 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
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170529/fef02bcb/attachment.html>


More information about the swift-evolution mailing list