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

Susan Cheng susan.doggie at gmail.com
Wed Jun 7 02:17:23 CDT 2017


Argument lists should or shouldn't be tuples. I think the question likes a
concept more than a technical question.

2017-06-07 14:56 GMT+08:00 Xiaodi Wu <xiaodi.wu at gmail.com>:

> On Wed, Jun 7, 2017 at 01:51 Susan Cheng <susan.doggie at gmail.com> wrote:
>
>> I don't think it's a roll back change.
>>
>
> Function argument lists were once tuples, but they have not been for many
> years. All of the proposals I listed above proceed on the basis that these
> are not the same. Your proposal says that function argument lists should be
> tuples: that is rolling back a >5 year old change, is it not?
>
> The proposal is not proposing allow to reorder the parameters by using the
>> tuple or implicit tuple splat to fit the function parameters.
>> It's just clarify the relationship of tuples and argument lists.
>>
>> as the grammar of Swift 3, it's allowed wrapping the argument with a
>> single tuple to a function with two argument.
>>
>> [(1, 2)].map(+)
>>
>> and SE-0110 is the proposal make the distinguished and not allowed this
>> line of code.
>>
>> although we fix the compiler to accept the destructuring of tuples
>>
>> [(1, 2)].map({ ((lhs, rhs)) in lhs + rhs })
>>
>> it's not accepting the code of [(1, 2)].map(+) which the operator + are
>> not function with accepting the tuple of two elements.
>>
>> the only way we can thought is that the arguments with single tuple is
>> flattened and it's most compatible with Swift 3.
>>
>> 2017-06-07 13:05 GMT+08:00 Xiaodi Wu <xiaodi.wu at gmail.com>:
>>
>>> 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/e3be0af5/attachment-0001.html>


More information about the swift-evolution mailing list