I like the idea of the case let syntax option except for the fact that we have existing syntax for decomposing tuples that doesn’t use case-
let (_, age) = arg Reusing this syntax feels like a better option than introducing a slight variant of it just for closures- let eighteenOrMore = ["Tom" : 33, "Rebecca" : 17, "Siri" : 5].filter { let (_, age) in return age >= 18 } -Simon > On 2 Jun 2017, at 12:25 pm, Tommaso Piazza via swift-evolution > <swift-evolution@swift.org> wrote: > > Thanks, added. > > > On Friday, June 2, 2017 1:18 PM, Vladimir.S <sva...@gmail.com> wrote: > > > On 02.06.2017 2:34, Tommaso Piazza wrote: > > Is the version you suggest to add to my list for the Swift syntax currently > > valid as > > of SE-0110 in Swift 4? > > Yes, just checked on latest dev snapshot of Swift 4. > > > > > > > On Thursday, June 1, 2017 9:32 PM, Vladimir.S <sva...@gmail.com > > <mailto:sva...@gmail.com>> wrote: > > > > > > On 01.06.2017 19:31, Tommaso Piazza wrote: > > > Dear all, > > > > > > I made a comparison of Swift's 4 lack of tuple unsplatting, here is how > > it stands in > > > comparison with other languages > > > > > > https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935 > > <https://gist.github.com/blender/53f9568617654c38a219dd4a8353d935> > > > > > > > Thank you! Very useful information. And also I really like the opinion of > > @AliSoftware in comments for this article. > > > > I'd suggest to add this variant to Swift section in your article: > > > > let eighteenOrMore = ["Tom" : 33, "Rebecca" : 17, "Siri" : 5].filter { > > (arg: (name: String, age: Int)) in arg.age >= 18 } > > > > (I believe it is better that 2 others Swift variants.) > > > > It seems for me that we need to allow some special syntax for *explicit* > > tuple > > destructuring in closures to make all happy. > > > > FWIW These suggestions are my favorite: > > > > 1. Just allow type inference for tuple's destructured variables in this > > position: > > > > .filter { (arg: (name, age)) in arg.age >= 18 } > > > > > > 2. (1) + allow underscore for tuple argument name: > > > > .filter { (_: (name, age)) in age >= 18 } > > > > > > 3. (2) + allow to omit parenthesis (probably only in case of just one tuple > > argument) > > > > .filter { _: (name, age) in age >= 18 } > > > > > > 4. Use pattern matching syntax: > > > > .filter { case let (name, age) in age >= 18 } > > > > (looks similar as allowed today: if case let (name, age) = x { print(name, > > age) } ) > > > > > > 5. Use two pairs of parenthesis : > > > > .filter { ((name, age)) in age >= 18 } > > > > Btw, about the 5th variant. If took what is allowed today: > > .filter { (arg: (name: String, age: Int)) in arg.age >= 18 } > > , and allow type inference for tuple part arguments, we'll have this: > > .filter { (arg: (name, age)) in arg.age >= 18 } > > , and if additionally allow skipping of tuple argument declaration we'll > > have: > > .filter { ((name, age)) in arg.age >= 18 } > > I.e. two pairs for parenthesis for tuple destructuring, and such syntax is > > similar to > > the type this closure should have : ((String, Int)) -> Bool > > > > > > > > > > > > > > > > On Thursday, June 1, 2017 12:25 PM, Vladimir.S via swift-evolution > > > <swift-evolution@swift.org <mailto:swift-evolution@swift.org> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> > > wrote: > > > > > > > > > On 01.06.2017 0:42, John McCall wrote: > > > >> On May 31, 2017, at 2:02 PM, Stephen Celis <stephen.ce...@gmail.com > > <mailto:stephen.ce...@gmail.com> > > <mailto:stephen.ce...@gmail.com <mailto:stephen.ce...@gmail.com>> > > > <mailto:stephen.ce...@gmail.com <mailto:stephen.ce...@gmail.com> > > <mailto:stephen.ce...@gmail.com <mailto:stephen.ce...@gmail.com>>>> wrote: > > > >>> On May 28, 2017, at 7:04 PM, John McCall via swift-evolution > > > >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>>> > > wrote: > > > >>> > > > >>> Yes, I agree. 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. > > > >> > > > >> Closure parameter lists are unfortunately only half of the equation > > here. This > > > >> change also regresses the usability of point-free expression. > > > > > > > > The consequences for point-free style were expected and cannot really > > be > > > > eliminated without substantially weakening SE-0110. Closure > > convenience seems to > > > > me to be a much more serious regression. > > > > > > John, do you also want to say "and without weakening SE-0066"? Because, > > if I > > > understand correctly, in this case: > > > > > > func add(_ x: Int, _ y: Int) -> Int { > > > return x + y > > > } > > > > > > zip([1, 2, 3], [4, 5, 6]).map(add) > > > > > > .. we have a clear function type mismatch situation, when map() expects > > function of > > > type ((Int, Int))->Int, but function of type (Int,Int)->Int is provided > > ? So probably > > > the additional 'reason' of the 'problem' in this case is SE-0066, no? > > > Or I don't understand the SE-0066 correctly.. > > > Do we want to allow implicit conversions between function type > > ((Int,Int))->Int and > > > (Int,Int)->Int? > > > > > > Quote from SE-0066: > > > --- > > > (Int, Int) -> Int // function from Int and Int to Int > > > ((Int, Int)) -> Int // function from tuple (Int, Int) to Int > > > --- > > > > > > During this discussion I see a wish of some group of developers to just > > return back > > > tuple splatting for function/closure arguments, so they can freely send > > tuple to > > > function/closure accepting a list of parameters(and probably vise-versa). > > > Is it worth to follow SE-0066 and SE-0110 as is, i.e. disallow tuple > > deconstructing > > > and then, as additive change improve the situation with tuple > > > splatting/deconstructing later with separate big proposal? > > > > > > Btw, about the SE-0110 proposal. It was discussed, formally reviewed and > > accepted. I > > > expect that its revision also should be formally > > proposed/reviewed/accepted to > > > collect a wide range of opinions and thoughts, and attract the attention > > of > > > developers in this list to the subject. > > > > > > > > > Also, if we revisit SE-0110, will this code be allowed?: > > > > > > func foo(_ callback: ((Int,Int))->Void) {} > > > let mycallback = {(x:Int, y:Int)->Void in } > > > foo(mycallback) > > > > > > and > > > > > > func foo(_ callback: (Int,Int)->Void) {} > > > let mycallback = {(x: (Int, Int))->Void in } > > > foo(mycallback) > > > > > > If so, what will be result of this for both cases? : > > > > > > print(type(of:mycallback)) // (Int,Int)->Void or ((Int,Int))->Void > > > > > > If allowed, do we want to allow implicit conversion between types > > (Int,Int)->Void and > > > ((Int,Int))->Void in both directions? (Hello tuple splatting?) > > > > > > > > > > > > > > John. > > > > > > > > > > > >> > > > >> func add(_ x: Int, _ y: Int) -> Int { return x + y } > > > >> > > > >> zip([1, 2, 3], [4, 5, 6]).map(add) > > > >> > > > >> // error: nested tuple parameter '(Int, Int)' of function > > '(((_.Element, > > > >> _.Element)) throws -> _) throws -> [_]' does not support > > destructuring > > > >> > > > >> This may not be a common pattern in most projects, but we heavily > > use this style > > > >> in the Kickstarter app in our functional and FRP code. Definitely > > not the most > > > >> common coding pattern, but a very expressive one that we rely on. > > > >> > > > >> Our interim solution is a bunch of overloaded helpers, e.g.: > > > >> > > > >> func tupleUp<A, B, C>(_ f: (A, B) -> C) -> ((A, B)) -> C { return } > > > >> > > > >> zip([1, 2, 3], [4, 5, 6]).map(tupleUp(add)) > > > >> > > > >> Stephen > > > > > > > > . > > > > > > > _______________________________________________ > > > swift-evolution mailing list > > > > swift-evolution@swift.org <mailto:swift-evolution@swift.org> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org> > > <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> > > > > > https://lists.swift.org/mailman/listinfo/swift-evolution > > <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > > > > > > > > > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution