<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_1496431447786_4791"><span>Thanks, added.</span></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 Friday, June 2, 2017 1:18 PM, Vladimir.S <svabox@gmail.com> wrote:<br></font></div> <br><br> <div class="y_msg_container"><div dir="ltr">On 02.06.2017 2:34, Tommaso Piazza wrote:<br clear="none">> Is the version you suggest to add to my list for the Swift syntax currently valid as <br clear="none">> of SE-0110 in Swift 4?<br clear="none"><br clear="none">Yes, just checked on latest dev snapshot of Swift 4.<br clear="none"><br clear="none">> <br clear="none">> <br clear="none">> On Thursday, June 1, 2017 9:32 PM, Vladimir.S <<a shape="rect" ymailto="mailto:svabox@gmail.com" href="mailto:svabox@gmail.com">svabox@gmail.com</a>> wrote:<br clear="none">> <br clear="none">> <br clear="none">> On 01.06.2017 19:31, Tommaso Piazza wrote:<br clear="none">> > Dear all,<br clear="none">> ><br clear="none">> > I made a comparison of Swift's 4 lack of tuple unsplatting, here is how it stands in<br clear="none">> > comparison with other languages<br clear="none">> ><br clear="none">> > <a shape="rect" href="https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935" target="_blank">https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935</a><br clear="none">> ><br clear="none">> <br clear="none">> Thank you! Very useful information. And also I really like the opinion of<br clear="none">> @AliSoftware in comments for this article.<br clear="none">> <br clear="none">> I'd suggest to add this variant to Swift section in your article:<br clear="none">> <br clear="none">> let eighteenOrMore = ["Tom" : 33, "Rebecca" : 17, "Siri" : 5].filter {<br clear="none">> (arg: (name: String, age: Int)) in arg.age >= 18 }<br clear="none">> <br clear="none">> (I believe it is better that 2 others Swift variants.)<br clear="none">> <br clear="none">> It seems for me that we need to allow some special syntax for *explicit* tuple<br clear="none">> destructuring in closures to make all happy.<br clear="none">> <br clear="none">> FWIW These suggestions are my favorite:<br clear="none">> <br clear="none">> 1. Just allow type inference for tuple's destructured variables in this position:<br clear="none">> <br clear="none">> .filter { (arg: (name, age)) in arg.age >= 18 }<br clear="none">> <br clear="none">> <br clear="none">> 2. (1) + allow underscore for tuple argument name:<br clear="none">> <br clear="none">> .filter { (_: (name, age)) in age >= 18 }<br clear="none">> <br clear="none">> <br clear="none">> 3. (2) + allow to omit parenthesis (probably only in case of just one tuple argument)<br clear="none">> <br clear="none">> .filter { _: (name, age) in age >= 18 }<br clear="none">> <br clear="none">> <br clear="none">> 4. Use pattern matching syntax:<br clear="none">> <br clear="none">> .filter { case let (name, age) in age >= 18 }<br clear="none">> <br clear="none">> (looks similar as allowed today: if case let (name, age) = x { print(name, age) } )<br clear="none">> <br clear="none">> <br clear="none">> 5. Use two pairs of parenthesis :<br clear="none">> <br clear="none">> .filter { ((name, age)) in age >= 18 }<br clear="none">> <br clear="none">> Btw, about the 5th variant. If took what is allowed today:<br clear="none">> .filter { (arg: (name: String, age: Int)) in arg.age >= 18 }<br clear="none">> , and allow type inference for tuple part arguments, we'll have this:<br clear="none">> .filter { (arg: (name, age)) in arg.age >= 18 }<br clear="none">> , and if additionally allow skipping of tuple argument declaration we'll have:<br clear="none">> .filter { ((name, age)) in arg.age >= 18 }<br clear="none">> I.e. two pairs for parenthesis for tuple destructuring, and such syntax is similar to<br clear="none">> the type this closure should have : ((String, Int)) -> Bool<br clear="none">> <br clear="none">> <br clear="none">> ><br clear="none">> ><br clear="none">> ><br clear="none">> > On Thursday, June 1, 2017 12:25 PM, Vladimir.S via swift-evolution<br clear="none">> > <<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>> wrote:<br clear="none">> ><br clear="none">> ><br clear="none">> > On 01.06.2017 0:42, John McCall wrote:<br clear="none">> > >> On May 31, 2017, at 2:02 PM, Stephen Celis <<a shape="rect" ymailto="mailto:stephen.celis@gmail.com" href="mailto:stephen.celis@gmail.com">stephen.celis@gmail.com</a> <br clear="none">> <mailto:<a shape="rect" ymailto="mailto:stephen.celis@gmail.com" href="mailto:stephen.celis@gmail.com">stephen.celis@gmail.com</a>><br clear="none">> > <mailto:<a shape="rect" ymailto="mailto:stephen.celis@gmail.com" href="mailto:stephen.celis@gmail.com">stephen.celis@gmail.com</a> <mailto:<a shape="rect" ymailto="mailto:stephen.celis@gmail.com" href="mailto:stephen.celis@gmail.com">stephen.celis@gmail.com</a>>>> wrote:<br clear="none">> > >>> On May 28, 2017, at 7:04 PM, John McCall via swift-evolution<br clear="none">> > >>> <<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> <br clear="none">> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>>> wrote:<br clear="none">> > >>><br clear="none">> > >>> Yes, I agree. We need to add back tuple destructuring in closure parameter<br clear="none">> > >>> lists because this is a serious usability regression. If we're reluctant to<br clear="none">> > >>> just "do the right thing" to handle the ambiguity of (a,b), we should at least<br clear="none">> > >>> allow it via unambiguous syntax like ((a,b)). I do think that we should just<br clear="none">> > >>> "do the right thing", however, with my biggest concern being whether there's<br clear="none">> > >>> any reasonable way to achieve that in 4.0.<br clear="none">> > >><br clear="none">> > >> Closure parameter lists are unfortunately only half of the equation here. This<br clear="none">> > >> change also regresses the usability of point-free expression.<br clear="none">> > ><br clear="none">> > > The consequences for point-free style were expected and cannot really be<br clear="none">> > > eliminated without substantially weakening SE-0110. Closure convenience seems to<br clear="none">> > > 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">> > func add(_ x: Int, _ y: Int) -> Int {<br clear="none">> > return x + y<br clear="none">> > }<br clear="none">> ><br clear="none">> > 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))->Int, but function of type (Int,Int)->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))->Int and<br clear="none">> > (Int,Int)->Int?<br clear="none">> ><br clear="none">> > Quote from SE-0066:<br clear="none">> > ---<br clear="none">> > (Int, Int) -> Int // function from Int and Int to Int<br clear="none">> > ((Int, Int)) -> Int // 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))->Void) {}<br clear="none">> > let mycallback = {(x:Int, y:Int)->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)->Void) {}<br clear="none">> > let mycallback = {(x: (Int, Int))->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)->Void or ((Int,Int))->Void<br clear="none">> ><br clear="none">> > If allowed, do we want to allow implicit conversion between types (Int,Int)->Void and<br clear="none">> > ((Int,Int))->Void in both directions? (Hello tuple splatting?)<br clear="none">> ><br clear="none">> ><br clear="none">> > ><br clear="none">> > > John.<br clear="none">> > ><br clear="none">> > ><br clear="none">> > >><br clear="none">> > >> func add(_ x: Int, _ y: Int) -> Int { return x + y }<br clear="none">> > >><br clear="none">> > >> zip([1, 2, 3], [4, 5, 6]).map(add)<br clear="none">> > >><br clear="none">> > >> // error: nested tuple parameter '(Int, Int)' of function '(((_.Element,<br clear="none">> > >> _.Element)) throws -> _) throws -> [_]' does not support destructuring<br clear="none">> > >><br clear="none">> > >> This may not be a common pattern in most projects, but we heavily use this style<br clear="none">> > >> in the Kickstarter app in our functional and FRP code. Definitely not the most<br clear="none">> > >> common coding pattern, but a very expressive one that we rely on.<br clear="none">> > >><br clear="none">> > >> Our interim solution is a bunch of overloaded helpers, e.g.:<br clear="none">> > >><br clear="none">> > >> func tupleUp<A, B, C>(_ f: (A, B) -> C) -> ((A, B)) -> C { return }<br clear="none">> > >><br clear="none">> > >> zip([1, 2, 3], [4, 5, 6]).map(tupleUp(add))<br clear="none">> > >><br clear="none">> > >> Stephen<br clear="none">> > ><br clear="none">> > > .<br clear="none">> > ><br clear="none">> > _______________________________________________<br clear="none">> > swift-evolution mailing list<div class="yqt9433621530" id="yqtfd45114"><br clear="none">> > <a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> <br clear="none">> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a> <mailto:<a shape="rect" ymailto="mailto:swift-evolution@swift.org" href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>><br clear="none">> <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">> ><br clear="none">> ><br clear="none">> <br clear="none">> <br clear="none"></div></div><br><br></div> </div> </div> </div></div></body></html>