[swift-evolution] [pitch] Eliminate the "T1 -> T2" syntax, require "(T1) -> T2"
Vladimir.S
svabox at gmail.com
Wed Apr 20 02:02:04 CDT 2016
Great points! We definitely have some mess with tuples¶meters list in
current Swift. Especially after we removed tuple splat feature.
But right now can't see what we can do about this.
(T1,T2) -> (T3,T4) really reads as "tuple (T1,T2) to tuple (T3,T4)" and
this is partially true as result is really tuple (T3,T4).
Correct form looks like T1,T2 -> (T3,T4), but this just can't be expressed
in current syntax of Swift - we need parens for param names, their
modifiers like inout/@noescape etc., don't think Swift can parse without
parens.
Even more. This is ok in current Swift 3:
let f : ((Int, Int)) -> (Int, Int) = { return ($0, $1) }
let f2 : ((Int, Int)) -> (Int, Int) = { return ($0.0, $0.1) }
I.e. absolutely the same functions, declared in different way. Why it
allows to point a tuple to $0 & $1, instead of just $0.0 $0.1 ?
On 19.04.2016 21:24, David Owens II via swift-evolution wrote:
> I have a different read of the proposal I guess... I actually find that this:
>
> (Int, Int) -> (Int, Int)
>
>
> Naturally reads take a single pair (e.g. tuple) of (Int, Int) and return a
> single pair of (Int, Int)
>
> This actually looks and feels like the right implementation to me:
>
> let tx: (Int, Int) -> (Int, Int) = { ($0.1, $0.0) }
>
>
> And I am saying that this would be explicitly wrong:
>
> let tx: (Int, Int) -> (Int, Int) = { ($1, $0) }
>
>
> If I wanted a type signature of that took two Int params, I would expect to
> write this:
>
> let tx: Int, Int -> (Int, Int) = { ($1, $0) }
>
>
> That reads, a type signature that takes two Int values and returns a single
> (Int, Int) pair.
>
> The problem, to me at least, is that the function declaration overloads the
> meaning of () as "start of parameter list for function declaration".
>
> func tx((Int, Int)) -> (Int, Int) { return ($0.1, $0.0) }
>
>
> So now you have this mess to say the same thing: take a single pair of Int
> and return a pair of Int.
>
> Similarly, if the () are going to required for parameter lists in function
> declarations, I really struggle to see why these two forms should mean the
> same thing:
>
> y = x.sorted { (lhs, rhs) in rhs < lhs }
> y = x.sorted { lhs, rhs in rhs < lhs }
>
>
> Dropping the type signatures because that can be inferred is one thing, but
> changing the structure of the parameter list seems like an orthogonal
> optimization.
>
> y = x.sorted { (lhs : Int, rhs : Int) -> Bool in rhs < lhs }
> y = x.sorted { (lhs, rhs) in rhs < lhs }
> { $1 < $0 }
>
>
> This process keeps the structural elements while dropping all of the type
> pieces and maintains the consistency that in function types (regardless of
> how they are defined), the () denotes a parameter list. If you actually
> want a tuple within the parameter list, you need to do `((lhs, rhs))`.
>
> -David
>
>> On Apr 19, 2016, at 9:24 AM, Erica Sadun via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>
>>
>>> On Apr 19, 2016, at 9:44 AM, David Rönnqvist <david.ronnqvist at gmail.com
>>> <mailto:david.ronnqvist at gmail.com>> wrote:
>>>
>>> Would this also affect the syntax for naming closure arguments? For
>>> example, would this (taken from "The Swift Programming Language (Swift
>>> 2.2)”):
>>>
>>> 1. |reversed = names.sort( { s1, s2 in return s1 > s2 } )|
>>>
>>> have to be written like this:
>>>
>>> 1. |reversed = names.sort( { (s1, s2) in return s1 > s2 } )|
>>>
>>> or is that a different syntax?
>>>
>>> As a developer focused on _writing_ and _reading_ code like this, I
>>> don’t see the real benefits of this change. It only feels natural to me
>>> that I would be able to omit the parentheses when there is only one
>>> type, but that I would need them to group multiple arguments or to label
>>> arguments.
>>>
>>> That said, I don’t feel strongly about it and the work of transitioning
>>> our code would be minimal. If this change provides other engineering
>>> benefits that aren’t noticeable on the surface, then I’m positive to the
>>> change for those reasons.
>>>
>>> - David
>>
>> It would not affect the closure syntax. To paraphrase Chris:
>>
>> No. Swift’s syntactic shortcuts in its closure parameter lists benefit
>> simple functional algorithms. Few people would choose to write fully
>> specified long-form declarations when, for example, reverse-sorting an
>> array of integers:
>>
>> |y = x.sorted { (lhs : Int, rhs : Int) -> Bool in rhs < lhs }|
>>
>> Compare the long form with this simpler form:
>>
>> |y = x.sorted { lhs, rhs in rhs < lhs }|
>>
>> You can use the even shorter form of |{ $1 < $0 }|.
>>
>> Closures offer a structurally distinct class of syntactic sugar:
>>
>> * You may elide parentheses (even with multiple arguments)
>> * You may omit the return type
>> * You may omit types
>> * You may omit the parameter list in its entirety
>>
>> Short of a complete rethink of closure syntax, requiring parentheses
>> there would not improve the language in any measurable way.
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list