[swift-evolution] Proposal: Always flatten the single element tuple

Xiaodi Wu xiaodi.wu at gmail.com
Wed Jun 7 00:05:04 CDT 2017


This is not what was meant during discussion about re-evaluating SE-0110.
Tuples already behave as described, but function argument lists are not
tuples and have not been for a very long time: see SE-0029, SE-0066.

Also, consider SE-0046, which makes possible labels in single-argument
argument lists (not possible in tuples), and SE-0060, which prohibits
arbitrary reordering (although still possible in tuples). This is to say
that the whole direction of Swift since version 2 has been to erase the
historical relationship between tuples and argument lists.

The question is how to accommodate some common use cases for destructuring
as a matter of syntactic sugar after having carefully distinguished
argument lists and tuples in the compiler, which is a given, not how to
roll back a change that was settled in 2011, by Chris’s telling.
On Tue, Jun 6, 2017 at 23:14 Susan Cheng via swift-evolution <
swift-evolution at swift.org> wrote:

>
> func add2(_ pair: (Int, Int)) -> Int {
>     return pair.0 + pair.1
> }
>
> consider the follows
>
> let _add2 =  add2     // add2 have the typeof `((Int, Int)) -> Int`, it
> should flatten to `(Int, Int) -> Int`
>
> so these two lines are also acceptable
> [(1, 2)].map(add1)
> [(1, 2)].map(add2)
>
> this proposal is not just changing the behaviour of closure, this proposal
> also changing the tuple type
>
> (((Int, Int)))   flatten to   (Int, Int)
> (Int, (((Int, Int))), Int)   flatten to   (Int, (Int, Int), Int)
>
>
> 2017-06-07 12:03 GMT+08:00 Stephen Celis <stephen.celis at gmail.com>:
>
>> The inline cases make sense to me, but my concern for ambiguity are
>> because we can define both of these functions:
>>
>>     func add1(_ x: Int, _ y: Int) -> Int {
>>       return x + y
>>     }
>>     func add2(_ pair: (Int, Int)) -> Int {
>>       return pair.0 + pair.1
>>     }
>>
>>     // What's the behavior here?
>>     [(1, 2)].map(add1)
>>     [(1, 2)].map(add2)
>>
>> What comes to mind, though, is, Swift already prevents single-element
>> tuples, so why not prevent functions that take a single tuple as the only
>> argument?
>>
>> Swift could provide a fix-it for functions that take single tuples and
>> say: "Swift functions cannot take a single tuple. Please write a function
>> that takes as many arguments as the tuple specified."
>>
>> Considering the fact that Swift generally operates in a multi-argument
>> world, and given that functions taking a single tuple are the minority, I
>> think this would be a good way to move forward.
>>
>> Stephen
>>
>> > On Jun 6, 2017, at 11:21 PM, Susan Cheng <susan.doggie at gmail.com>
>> wrote:
>> >
>> >  [(1, 2)].map({ x, y in x + y })  // this line is correct
>> >  [(1, 2)].map({ tuple in tuple.0 + tuple.1 })  // this line should not
>> accepted
>> >
>> > or
>> >
>> >  [(1, 2)].map({ $0 + $1 })  // this line is correct
>> >  [(1, 2)].map({ $0.0 + $0.1 })  // this line should not accepted
>> >
>> > it's because `((Int, Int)) -> Int` always flatten to `(Int, Int) -> Int`
>> > so, it should only accept the function with two arguments
>> >
>> >
>> >
>> > 2017-06-07 11:07 GMT+08:00 Stephen Celis <stephen.celis at gmail.com>:
>> > I like this a lot, but how do we solve for the function case?
>> >
>> >     func add(_ x: Int, _ y: Int) -> Int {
>> >       return x + y
>> >     }
>> >     [(1, 2)].map(add)
>> >
>> > Where does `map` with a function of `((Int, Int)) -> Int` fit in?
>> >
>> > > On Jun 6, 2017, at 10:15 PM, Susan Cheng via swift-evolution <
>> swift-evolution at swift.org> wrote:
>> > >
>> > > Introduction
>> > >
>> > >
>> > > Because the painful of SE-0110, here is a proposal to clarify the
>> tuple syntax.
>> > >
>> > > Proposed solution
>> > >
>> > > 1. single element tuple always be flattened
>> > >
>> > > let tuple1: (((Int))) = 0  // TypeOf(tuple1) == Int
>> > >
>> > > let tuple2: ((((Int))), Int) = (0, 0)  // TypeOf(tuple2) == (Int, Int)
>> > >
>> > > 2. function arguments list also consider as a tuple, which means the
>> function that accept a single tuple should always be flattened.
>> > >
>> > > let fn1: (Int, Int) -> Void = { _, _ in }
>> > >
>> > > let fn2: ((Int, Int)) -> Void = { _, _ in }  // always flattened
>> > >
>> > > let fn3: (Int, Int) -> Void = { _ in }  // not allowed, here are two
>> arguments
>> > >
>> > > let fn4: ((Int, Int)) -> Void = { _ in }  // not allowed, here are
>> two arguments
>> > >
>> > > _______________________________________________
>> > > swift-evolution mailing list
>> > > 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170607/6c47583f/attachment.html>


More information about the swift-evolution mailing list