<div dir="ltr">Vladimir, using your function definitions I would like to have:<div><br></div><div><font face="monospace, monospace">// Two parameters:</font></div><div><div><span style="font-family:monospace,monospace">barParams{ t in } <font color="#cc0000">// invalid, </font></span><font color="#cc0000"><span style="font-family:monospace,monospace">too few</span><span style="font-family:monospace,monospace"> parameters</span></font></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barParams{ (t) in } <font color="#cc0000">// invalid, too few parameters</font></font></div></div><div><span style="font-family:monospace,monospace">barParams{ x, y in } <font color="#38761d">// valid, two parameters</font></span><br></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barParams{ (x, y) in } <font color="#38761d">// valid, two parameters with optional parentheses</font></font></div><div><span style="font-family:monospace,monospace">barParams{ ((x, y)) in }<font color="#cc0000">// invalid, </font></span><font color="#cc0000"><span style="font-family:monospace,monospace">too few</span><span style="font-family:monospace,monospace"> parameters</span></font></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">// One parameter which is a 2-tuple:</span></div><div><div><span style="font-family:monospace,monospace">barTuple{ t in } <font color="#38761d">// valid, one tuple parameter</font></span><br></div></div><div><div><span style="font-family:monospace,monospace">barTuple</span><span style="font-family:monospace,monospace">{ (t) in } <font color="#38761d">// valid, one tuple parameter with optional parentheses</font></span></div><div><span style="font-family:monospace,monospace"></span><span style="font-family:monospace,monospace">barTuple{ x, y in } <font color="#cc0000">// invalid, too many parameters</font></span><br></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barTuple{ (x, y) in } <font color="#38761d">// valid, </font></font><font color="#38761d"><span style="font-family:monospace,monospace">destructuring one </span><font face="monospace, monospace">tuple</font></font></div><div><span style="font-family:monospace,monospace">barTuple</span><span style="font-family:monospace,monospace">{ ((x, y)) in } <font color="#38761d">// valid, destructuring one tuple with optional parentheses</font></span><span style="font-family:monospace,monospace"><br></span></div><div><br></div></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Nevin</div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 29, 2017 at 1:32 PM, Vladimir.S <span dir="ltr"><<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote:<span class=""><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> <mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.<wbr>org</a>>> wrote:<br>
<br>
<br>
We need to add back tuple destructuring in closure parameter lists because this<br>
is a serious usability regression. If we're reluctant to just "do the right<br>
thing" to handle the ambiguity of (a,b), we should at least allow it via<br>
unambiguous syntax like ((a,b)). I do think that we should just "do the right<br>
thing", however, with my biggest concern being whether there's any reasonable way<br>
to achieve that in 4.0.<br>
<br>
John.<br>
<br>
<br>
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.<br>
<br>
Nevin<br>
</blockquote>
<br></span>
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:<br>
<br>
I.e.<br>
typealias FuncParams = (Int, Int)->()<br>
typealias FuncTuple = ((Int, Int))->()<br>
<br>
print(FuncParams.self) // should be (Int, Int)->()<br>
print(FuncTuple.self) // should be ((Int, Int))->()<br>
<br>
So, if we have<br>
<br>
func barParams(_ f: FuncParams) {<br>
f(1,2)<br>
}<br>
<br>
func barTuple(_ f: FuncTuple) {<br>
f((1,2))<br>
}<br>
<br>
and<br>
<br>
func fooWithParams(_ x: Int, _ y: Int) { }<br>
func fooWithTuple(_ tuple: (Int, Int)) { }<br>
<br>
.. we should not be able to call<br>
<br>
barParams(fooWithTuple) // should be error: incompatible types<br>
barTuple(fooWithParams) // should be error: incompatible types<br>
<br>
<br>
If so, are you suggesting that this code should still be valid?<br>
<br>
barParams({tuple in}) // ?<br>
barTuple({x,y in}) // ?<br>
<br>
<br>
Will {x,y in} closure has ((Int, Int))->() type in this case?<br>
And if {tuple in} should be of type (Int,Int)->() ?<br>
<br>
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:<br>
<br>
barTuple({((x,y)) in ... })<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br>
</blockquote>
</div></div></blockquote></div><br></div></div>