> On Jun 9, 2017, at 4:34 PM, Jens Persson <j...@bitcycle.com> wrote: > > The analogy of the special first parameter label was relevant (for me) in > that it was a special rule that was invented to resolve a problem/situation > with no clear best solution. Probably most people agree now that the current > simpler and more uniform rule set for parameter labels are obviously better. > It was possible to escape the ugly special case of the first parameter, after > all. > > Similarly, I wonder if the parentheses-related mess actually can be simpler > and more uniform, after all. I remember a lot of discussions in which people > argued that Swift couldn't and/or shouldn't get rid of the special first > parameter label rules. > > I'm not a compiler hacker and I have no idea exactly what aspects of the > language is easy/hard/impossible to change once Swift is binary stable. > > My concrete concerns are that the messy parentheses-related parts of the > language will continue to be messy for ever. > I have no idea if there is any actual reason to worry about that, but ABI > stability was originally intended for Swift 3, and then it was postponed > because some stuff needed to be done before ABI stability. Now I'm just > worried that solving the parentheses situation is something that needs to be > done before ABI stability. Please correct/enlighten me! >
Ah, rest assured that ABI stability (likely*) has little to do with your concerns. In theory, some post-ABI-stability Swift version could rename every single keyword and replace curly braces with “begin/end” and parens with emoji without affecting the ABI. Similarly, syntactic sugar and destructuring tuples shouldn’t affect ABI*. Source stability is what you’re likely confusing this with, which can be a little nebulous. * Unless you’re proposing a change to the semantics of the language that could affect e.g. name mangling or the type metadata hierarchy, then that would be ABI-affecting. For example, proposing that all functions must only take a single tuple rather than multiple arguments could affect the runtime representation of function types. But even then, there are approaches to mitigate this, so such a proposal would likely present an ABI migration strategy. > /Jens > > > > On Sat, Jun 10, 2017 at 12:50 AM, Michael Ilseman <milse...@apple.com > <mailto:milse...@apple.com>> wrote: > > > On Jun 9, 2017, at 2:10 PM, Jens Persson via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: > >> The point of exercise 1 is to show that it is impossible (in Swift 4) to >> write a generic function composition operator (or function) which works as >> expected for any reasonable functions. >> This was possible in Swift 3, but in Swift 4 it will only work for functions >> with exactly one parameter. You'd have to special-case it for every >> combination of parameter counts of f and g that it should be able to handle. >> >> The following program demonstrates how it can be done in Swift 3.1 and 3.2: >> >> func compose<T, U, V>(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> >> (T) -> V { >> return { x in g(f(x)) } >> } >> func sum(_ a: Int, _ b: Int) -> Int { return a + b } >> func square(_ a: Int) -> Int { return a * a } >> let squaredSum = compose(square, sum) >> let result = squaredSum((3, 4)) // A bit unexepected with a tuple here but >> ok ... >> print(result) // 49 >> // Well, it worked, not flawlessly but we did manage to write >> // a function composition function and we composed sum >> // and square, and we could call it and get a correct result. >> >> >> And this program demonstrates what happens if you try it in Swift 4: >> >> func compose<T, U, V>(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> >> (T) -> V { >> return { x in g(f(x)) } >> } >> func sum(_ a: Int, _ b: Int) -> Int { return a + b } >> func square(_ a: Int) -> Int { return a * a } >> // let squaredSum = compose(square, sum) // Error! (without the >> compose-variant below) >> >> // The error message is: >> // Cannot convert value of type `(Int, Int) -> Int` to >> // expected argument type `(_) -> _` >> >> // That's it, it is simply not possible! >> >> // You'd have to write special variants of the compose func for every >> combination >> // of parameter counts! For example, in order to get this sum and square >> // example working, this specific variant must be written: >> func compose<T, U, V, W>(_ g: @escaping (V) -> W, _ f: @escaping (T, U) -> >> V) -> (T, U) -> W { >> return { (x, y) in g(f(x, y)) } >> } >> // Now it will work: >> let squaredSum = compose(square, sum) >> // But only thanks to that awfully specific compose func variant ... >> // We would have to write a lot more variants for it to be practically >> usable on pretty much any common function. >> >> I'm sure some will say: >> "no regular developers use function composition anyway so why ..." >> or >> "It's not very swifty to use free functions and higher order functions like >> that." >> >> My answer is that this is just a simple but telling example. The issue (as I >> see it) exists in all situations involving generics and function types. >> >> I'm a regular programmer and I like to be able to write basic, useful >> abstractions. >> It's no fun when the language forces you to write lots of specific variants >> of your generic code. >> >> I would feel less worried about the parentheses situation if the language >> was going in a direction where you could see how this simple exercise would >> be a no brainer. >> >> Can Swift's parentheses-situation be sorted out before ABI stability? >> Otherwise it would be a bit like if Swift had kept the special rule for the >> first parameter, only much worse. >> > > Out of curiosity, how do you think this would impact ABI? What are your > concrete concerns here? > > I don't think the analogy of first parameter label is relevant, as that > needn't be ABI. > >> /Jens >> >> >> >> >> On Fri, Jun 9, 2017 at 7:17 PM, Gor Gyolchanyan <g...@gyolchanyan.com >> <mailto:g...@gyolchanyan.com>> wrote: >> Yes, except why would you need to define `((A, B)) -> C`?, If you need to >> pass a 2-element tuple into a function that takes two parameters - you can! >> If you want to pass two values into a function that *looks* like it takes a >> single 2-element tuple - you can! Seems to me that the difference between >> `((A, B)) -> C` and `(A, B) -> C` is virtually non-existent. But keep in >> mind that this only works for bare tuples (the ones that can't have labels). >> Non-closure functions DO have labels, which is part of their signature, so >> this is a different story. >> >>> On Jun 9, 2017, at 6:18 PM, Gwendal Roué <gwendal.r...@gmail.com >>> <mailto:gwendal.r...@gmail.com>> wrote: >>> >>> >>>> Le 9 juin 2017 à 17:12, Gor Gyolchanyan via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit : >>>> >>>>> >>>>> So I wonder if any of you have had any thoughts about what Swift's >>>>> parentheses-related future (or evolutionary baggage) will be? >>>>> >>>> >>>> I really wish swift used the concept of tuples **exclusively** for all >>>> purposes that involve parentheses, as well as dividing tuples into two >>>> categories: >>>> - Bare tuples, which do not have labels. >>>> - Rich tuples, which do. >>>> As a consequence, here's a list of statements that would become true: >>>> - All functions take exactly one parameter, which is a tuple. >>>> - All closures (a.k.a. function pointers) take exactly one parameter, >>>> which is a bare tuple. >>>> - All functions return exactly one parameter, which is a tuple. >>>> - Pattern matching is done on a single bare tuple using a single bare >>>> tuple pattern. >>>> >>>> The currently ongoing proposal to make a single-element tuple auto-flatten >>>> would work extremely well with this idea, by making all these changes >>>> completely backward-compatible. >>> >>> If I have well understood, Swift has evolved away from this. >>> >>> If what you describe were true, added to the fact that there is no such >>> thing as a one-element tuple in the language, then (A,B) -> C and ((A, B)) >>> -> C could not be distinguished, for the simple reason that ((A, B)) -> C >>> could not be defined. >>> >>> For ((A, B)) -> C to be defined, we'd need a function that takes exactly >>> one parameter, which is a tuple (your idea), whose single element is a >>> tuple (oops, there is no single-valued tuples). >>> >>> No opinion here, just they way I have understood recent Swift history. >>> Gwendal >>> >> >> >> _______________________________________________ >> swift-evolution mailing list >> 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