<html><head></head><body><div style="color:#000; background-color:#fff; font-family:Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:13px"><div id="yui_3_16_0_ym19_1_1496334381862_9313"><span></span></div><div id="yui_3_16_0_ym19_1_1496334381862_9313">Dear all,</div><div id="yui_3_16_0_ym19_1_1496334381862_9313"><br></div><div id="yui_3_16_0_ym19_1_1496334381862_9313" dir="ltr">I made a comparison of Swift's 4 lack of tuple unsplatting, here is how it stands in comparison with other languages</div><div id="yui_3_16_0_ym19_1_1496334381862_9313" dir="ltr"><br></div><div id="yui_3_16_0_ym19_1_1496334381862_9313" dir="ltr">&nbsp;<a href="https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935" id="yui_3_16_0_ym19_1_1496334381862_13434" class="">https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935</a></div><div id="yui_3_16_0_ym19_1_1496334381862_13442"><br></div><div id="yui_3_16_0_ym19_1_1496334381862_13444"><br></div> <div class="qtdSeparateBR"><br><br></div><div class="yahoo_quoted" style="display: block;"> <div style="font-family: Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 13px;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 16px;"> <div dir="ltr"><font size="2" face="Arial"> On Thursday, June 1, 2017 12:25 PM, Vladimir.S via swift-evolution &lt;swift-evolution@swift.org&gt; wrote:<br></font></div>  <br><br> <div class="y_msg_container"><div dir="ltr">On 01.06.2017 0:42, John McCall wrote:<br clear="none">&gt;&gt; On May 31, 2017, at 2:02 PM, Stephen Celis &lt;<a shape="rect" ymailto="mailto:stephen.celis@gmail.com" href="mailto:stephen.celis@gmail.com">stephen.celis@gmail.com</a>&gt; wrote:<br clear="none">&gt;&gt;&gt; On May 28, 2017, at 7:04 PM, John McCall via swift-evolution<br clear="none">&gt;&gt;&gt; &lt;<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br clear="none">&gt;&gt;&gt; <br clear="none">&gt;&gt;&gt; Yes, I agree.&nbsp; We need to add back tuple destructuring in closure parameter<br clear="none">&gt;&gt;&gt; lists because this is a serious usability regression.&nbsp; If we're reluctant to<br clear="none">&gt;&gt;&gt; just "do the right thing" to handle the ambiguity of (a,b), we should at least<br clear="none">&gt;&gt;&gt; allow it via unambiguous syntax like ((a,b)).&nbsp; I do think that we should just<br clear="none">&gt;&gt;&gt; "do the right thing", however, with my biggest concern being whether there's<br clear="none">&gt;&gt;&gt; any reasonable way to achieve that in 4.0.<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; Closure parameter lists are unfortunately only half of the equation here. This<br clear="none">&gt;&gt; change also regresses the usability of point-free expression.<br clear="none">&gt; <br clear="none">&gt; The consequences for point-free style were expected and cannot really be<br clear="none">&gt; eliminated without substantially weakening SE-0110.&nbsp; Closure convenience seems to<br clear="none">&gt; me to be a much more serious regression.<br clear="none"><br clear="none">John, do you also want to say "and without weakening SE-0066"? Because, if I <br clear="none">understand correctly, in this case:<br clear="none"><br clear="none">&nbsp; func add(_ x: Int, _ y: Int) -&gt; Int {<br clear="none">&nbsp; &nbsp;  return x + y<br clear="none">&nbsp;  }<br clear="none"><br clear="none">&nbsp;  zip([1, 2, 3], [4, 5, 6]).map(add)<br clear="none"><br clear="none">.. we have a clear function type mismatch situation, when map() expects function of <br clear="none">type ((Int, Int))-&gt;Int, but function of type (Int,Int)-&gt;Int is provided ? So probably <br clear="none">the additional 'reason' of the 'problem' in this case is SE-0066, no?<br clear="none">Or I don't understand the SE-0066 correctly..<br clear="none">Do we want to allow implicit conversions between function type ((Int,Int))-&gt;Int and <br clear="none">(Int,Int)-&gt;Int?<br clear="none"><br clear="none">Quote from SE-0066:<br clear="none">---<br clear="none">(Int, Int) -&gt; Int&nbsp; &nbsp; // function from Int and Int to Int<br clear="none">((Int, Int)) -&gt; Int&nbsp; // function from tuple (Int, Int) to Int<br clear="none">---<br clear="none"><br clear="none">During this discussion I see a wish of some group of developers to just return back <br clear="none">tuple splatting for function/closure arguments, so they can freely send tuple to <br clear="none">function/closure accepting a list of parameters(and probably vise-versa).<br clear="none">Is it worth to follow SE-0066 and SE-0110 as is, i.e. disallow tuple deconstructing <br clear="none">and then, as additive change improve the situation with tuple <br clear="none">splatting/deconstructing later with separate big proposal?<br clear="none"><br clear="none">Btw, about the SE-0110 proposal. It was discussed, formally reviewed and accepted. I <br clear="none">expect that its revision also should be formally proposed/reviewed/accepted to <br clear="none">collect a wide range of opinions and thoughts, and attract the attention of <br clear="none">developers in this list to the subject.<br clear="none"><br clear="none"><br clear="none">Also, if we revisit SE-0110, will this code be allowed?:<br clear="none"><br clear="none">func foo(_ callback: ((Int,Int))-&gt;Void) {}<br clear="none">let mycallback = {(x:Int, y:Int)-&gt;Void in }<br clear="none">foo(mycallback)<br clear="none"><br clear="none">and<br clear="none"><br clear="none">func foo(_ callback: (Int,Int)-&gt;Void) {}<br clear="none">let mycallback = {(x: (Int, Int))-&gt;Void in }<br clear="none">foo(mycallback)<br clear="none"><br clear="none">If so, what will be result of this for both cases? :<br clear="none"><br clear="none">print(type(of:mycallback)) // (Int,Int)-&gt;Void or ((Int,Int))-&gt;Void<br clear="none"><br clear="none">If allowed, do we want to allow implicit conversion between types (Int,Int)-&gt;Void and <br clear="none">((Int,Int))-&gt;Void in both directions?&nbsp; (Hello tuple splatting?)<div class="yqt8923234069" id="yqtfd97796"><br clear="none"><br clear="none">&gt; <br clear="none">&gt; John.<br clear="none">&gt; <br clear="none">&gt; <br clear="none">&gt;&gt; <br clear="none">&gt;&gt; func add(_ x: Int, _ y: Int) -&gt; Int { return x + y }<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; zip([1, 2, 3], [4, 5, 6]).map(add)<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; // error: nested tuple parameter '(Int, Int)' of function '(((_.Element,<br clear="none">&gt;&gt; _.Element)) throws -&gt; _) throws -&gt; [_]' does not support destructuring<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; This may not be a common pattern in most projects, but we heavily use this style<br clear="none">&gt;&gt; in the Kickstarter app in our functional and FRP code. Definitely not the most<br clear="none">&gt;&gt; common coding pattern, but a very expressive one that we rely on.<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; Our interim solution is a bunch of overloaded helpers, e.g.:<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; func tupleUp&lt;A, B, C&gt;(_ f: (A, B) -&gt; C) -&gt; ((A, B)) -&gt; C { return }<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; zip([1, 2, 3], [4, 5, 6]).map(tupleUp(add))<br clear="none">&gt;&gt; <br clear="none">&gt;&gt; Stephen<br clear="none">&gt; <br clear="none">&gt; .<br clear="none">&gt; <br clear="none">_______________________________________________<br clear="none">swift-evolution mailing list<br clear="none"><a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br clear="none"><a shape="rect" href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br clear="none"></div></div><br><br></div>  </div> </div>  </div></div></body></html>