[swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

Xiaodi Wu xiaodi.wu at gmail.com
Fri May 5 02:14:21 CDT 2017


On Fri, May 5, 2017 at 1:44 AM, Robert Widmann <devteam.codafi at gmail.com>
wrote:

> I can see where you’re coming from, absolutely.  I don’t intend to remove
> necessary semantic content labels can provide if I don’t have to.
>
> For the sake of expediency - and because even with labels you can
> destructure into a label-less pattern, I’ll concede this point and remove
> the section about removing labeled patterns from the draft on Github.
>

Without that chunk, I would be fine with the proposal. It removes a clever
part of the language, but perhaps too clever and now rather unexpected,
with the direction in which it's evolving.


> ~Robert Widmann
>
> On May 5, 2017, at 2:35 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
> On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> On Fri, May 5, 2017 at 1:21 AM, Robert Widmann <devteam.codafi at gmail.com>
>> wrote:
>>
>>> Those labels anchored the reordering algorithm.  They guaranteed that
>>> structural typing thing I brought up where you had to consume all the
>>> labels in the type signature before you could continue, but that was where
>>> their semantic value ended.  Given an ordering invariant, what matters are
>>> the names *you* give to the values in the pattern.  Not the names given
>>> in, say, the return value of the function - which as part of the type are
>>> supposed to be irrelevant anyways.
>>>
>>
>> There's more to Swift's syntax than what's solely required for the
>> compiler to parse it. There are also the bits we put in to help humans
>> write correct code.
>>
>> This is one reason why SE-0111 was revised to permit "cosmetic" labels
>> for functions after their type system significance was removed. With
>> respect to tuples, I fully understand that if you remove the ability to
>> reorder indices of a tuple, labels in tuple patterns won't "do"
>> anything--other than assert that the poor human who's writing them has the
>> tuple elements in the right order. But that's important. That's valuable.
>>
>
> Put concretely:
>
> ```
> let tuple = (x: 1, y: 2)
>
> // I, silly human, mistakenly think the elements in the tuple are
> // `y` first, then `x`. I'm a confused human. Now I write:
>
> let (y: y, x: x) = tuple
> // Currently, does the right thing, even though I'm confused.
>
> let (y: y, x: x) = tuple
> // Without tuple reordering, this produces an error, which corrects my
> confusion.
>
> let (y, x) = tuple
> // Oops. I'm out of luck.
> ```
>
> Enum cases are a different kettle of fish since the last round of
>>> proposals (specifically SE-0155).  Associated value clauses are no longer
>>> tuples.
>>>
>>> Thank you for digging up that blog about this too.  I hadn't seen that
>>> before I went into this - it came up because of code review related to some
>>> fallout from SE-110.
>>>
>>> ~Robert Widmann
>>>
>>> 2017/05/05 2:09、Xiaodi Wu <xiaodi.wu at gmail.com> のメッセージ:
>>>
>>> On Fri, May 5, 2017 at 1:01 AM, Robert Widmann <devteam.codafi at gmail.com
>>> > wrote:
>>>
>>>>
>>>>
>>>> ~Robert Widmann
>>>>
>>>> 2017/05/05 1:42、Xiaodi Wu <xiaodi.wu at gmail.com> のメッセージ:
>>>>
>>>> On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi at gmail.com>
>>>> wrote:
>>>>
>>>>> On the contrary, this is precisely what it means to deprecate tuple
>>>>> shuffles.  You can’t map common parlance onto this term; the proposal and
>>>>> the Twitter thread weren’t merely about reordering arguments.
>>>>>
>>>>
>>>> Let's be clear: _all_ of your examples of "shuffles" in the proposal
>>>> involve reordering. You defined a tuple shuffle as such: "an undocumented
>>>> feature of Swift in which one can re-order the indices of a tuple...." If
>>>> you intend to propose a broader change, it is grossly misleading to write
>>>> it up in this way.
>>>>
>>>>
>>>> They are both modeled by shuffles.  And we are spinning off into
>>>> semantic weeds I'd rather not spin off into.  The core of your
>>>> counterargument is the pattern change being bad for business.  Let's
>>>> discuss that.
>>>>
>>>>
>>>> but it is entirely another ballgame to remove labels from tuple
>>>>> patterns altogether.
>>>>>
>>>>>
>>>>> It’s really not.  Let me demonstrate:
>>>>>
>>>>> To be clear, are you proposing the prohibition of *adding or removing*
>>>>>> labels as well? A previous discussion on tuple shuffling on this list saw
>>>>>> consensus that assigning a value of type (label1: T, label2: U) to a
>>>>>> variable of type (T, U) and vice versa should absolutely be supported,
>>>>>> whether or not reordering is permitted.
>>>>>
>>>>>
>>>>> I am not proposing any changes to switching parameter labels through
>>>>> well-typed re-assignments.  This is absolutely still going to be allowed:
>>>>>
>>>>> var z : (Int, Int) = (0, 0)
>>>>> var w : (x : Int, y : Int) = (5, 10)
>>>>> z = w
>>>>> w = z
>>>>>
>>>>> This is modeled internally with a tuple shuffle, but not the kind of
>>>>> shuffle I’m interested in banning.  It’s a far simpler kind of
>>>>>
>>>>
>>>> What is your proposed behavior for the following code?
>>>>
>>>> ```
>>>> let x: (r: Int, g: Int, b: Int, a: Int) = (255, 255, 255, 0)
>>>> let y: (a: Int, r: Int, g: Int, b: Int) = x
>>>>
>>>> print(y.a) // currently, prints "0"
>>>> ```
>>>>
>>>> Either you are proposing only to remove labels from tuple patterns,
>>>> which does not at all prohibit reordering, or you are proposing to prohibit
>>>> reordering, in which case this code has an error--or it doesn't and you've
>>>> instead _silently_ changed the behavior of existing code. One can live with
>>>> warnings and even errors, but a silent change to existing code is the stuff
>>>> of nightmares, and I would be strongly opposed to that.
>>>>
>>>>
>>>> This is a reordering.  Banned.  End of story.  This code is fragile and
>>>> demonstrates a key reason why we need to enforce an ordering invariant.
>>>>
>>>>
>>>>
>>>>>
>>>>> And how about *restating* existing labels without any adding or
>>>>>> removing? To be clear:
>>>>>>
>>>>>> ```
>>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>>> ```
>>>>>>
>>>>>> ...involves absolutely no changes in labels whatsoever. The return
>>>>>> type is (partialValue: Int, overflow: ArithmeticOverflow).
>>>>>>
>>>>>
>>>>> That, however, is a kind of shuffle I intend to deprecate here.  This
>>>>> kind of pattern is subject to the “arcane syntax” part of the proposal.
>>>>>
>>>>>
>>>>>> Either one of these scenarios is commonly used, and it is astonishing
>>>>>> to me that they would be eliminated.
>>>>>
>>>>>
>>>>> Do you have proof of that claim? I have never seen the relevant kinds
>>>>> of tuple shuffle used before, and I doubt you have either before today.
>>>>>
>>>>
>>>> Huh? I use it pervasively. Currently, writing out labels during
>>>> destructuring guarantees that, even if I've incorrectly memorized the order
>>>> of the values in a tuple, the tuple is still destructured as I expect. And
>>>> if reordering were not a feature of Swift, I would still write out these
>>>> labels. In that case, it would be a static assertion that destructuring is
>>>> happening in the expected order. That is, if I try to destructure a tuple
>>>> of type (r: Int, g: Int, b: Int, a: Int) and accidentally write 'let (a:
>>>> alpha, r: _, g: green, b: _) = ...', I'd get an error and find my mistake
>>>> at compile time.
>>>>
>>>> The whole point of having labels in the first place is clarity at the
>>>> point of use. Just as SE-0111 will need revision because it removed a key
>>>> documentation use for argument labels, forbidding labels in tuple patterns
>>>> would make the same mistake for tuples.
>>>>
>>>>
>>>> The intent at the time may have been to treat tuples as a kind of
>>>> structurally-typed thing, but shadowing concerns and reordering in patterns
>>>> means this kind of relabeling can be abused and shouldn't be trusted as a
>>>> kind of structural invariant in a pattern - as we seem to agree.  To me,
>>>> labels in tuple types provide a means of defining custom projections out of
>>>> the tuple, nothing more.  In patterns, I don't see a reason for them.
>>>>
>>>
>>> We can agree that relabeling can be abused, but it does not stand to
>>> reason that labeling (i.e. the correct, unchanged label) has no role in
>>> tuple patterns. Again, it serves as documentation for the pattern, just as
>>> labels serve as documentation for tuples, enum cases, and functions. There
>>> are many languages that see no reason for labels at all, but Swift is not
>>> one of those languages.
>>>
>>>
>>>>
>>>>
>>>>> ~Robert Widmann
>>>>>
>>>>> On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>>>
>>>>> Ah, I see from your proposed grammar update: you're proposing to
>>>>> prohibit the use of labels entirely in a tuple pattern.
>>>>>
>>>>> This is much more than just prohibiting tuple shuffling, and I'm
>>>>> rather disappointed that you described such a dramatic change using a
>>>>> corner case. There are very good reasons why someone finds 'let (y: x, x:
>>>>> y) = (x: 1, y: 2)' confusing and would support its removal, but it is
>>>>> entirely another ballgame to remove labels from tuple patterns altogether.
>>>>>
>>>>>
>>>>> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>>>
>>>>>> Now I'm confused. The ordinary meaning of the word "shuffle" is not
>>>>>> changing but rather reordering, and all of your examples are of reordering.
>>>>>>
>>>>>> To be clear, are you proposing the prohibition of *adding or
>>>>>> removing* labels as well? A previous discussion on tuple shuffling on this
>>>>>> list saw consensus that assigning a value of type (label1: T, label2: U) to
>>>>>> a variable of type (T, U) and vice versa should absolutely be supported,
>>>>>> whether or not reordering is permitted.
>>>>>>
>>>>>> And how about *restating* existing labels without any adding or
>>>>>> removing? To be clear:
>>>>>>
>>>>>> ```
>>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>>> ```
>>>>>>
>>>>>> ...involves absolutely no changes in labels whatsoever. The return
>>>>>> type is (partialValue: Int, overflow: ArithmeticOverflow).
>>>>>>
>>>>>> Either one of these scenarios is commonly used, and it is astonishing
>>>>>> to me that they would be eliminated.
>>>>>>
>>>>>> On Thu, May 4, 2017 at 23:28 Robert Widmann <devteam.codafi at gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>>> That doesn't involve a parameter *reordering*, but because it
>>>>>>> changes argument labels it's a shuffle.
>>>>>>>
>>>>>>> ~Robert Widmann
>>>>>>>
>>>>>>> 2017/05/05 0:16、Xiaodi Wu <xiaodi.wu at gmail.com> のメッセージ:
>>>>>>>
>>>>>>> Robert,
>>>>>>>
>>>>>>> As I mentioned on Twitter, getting rid of tuple shuffles would not
>>>>>>> cure your example, which does not involve a shuffle. Unless you're
>>>>>>> proposing to disallow the use of labels during destructuring entirely,
>>>>>>> which I would think to be very much unacceptable. Example:
>>>>>>>
>>>>>>> ```
>>>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>>>> ```
>>>>>>>
>>>>>>> This involves no shuffling and should absolutely remain allowed.
>>>>>>>
>>>>>>>
>>>>>>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution <
>>>>>>> swift-evolution at swift.org> wrote:
>>>>>>>
>>>>>>>> Hi all,
>>>>>>>>
>>>>>>>> So sorry that this proposal comes so late in the game, but I feel
>>>>>>>> it’s too important not to bring it to the attention of the community now.
>>>>>>>> Attached is a proposal to deprecate a language feature many of you will
>>>>>>>> probably have never had the chance to use: Tuple Shuffles.  I’ve attached a
>>>>>>>> copy of the first draft of the proposal below, but the latest copy can be
>>>>>>>> read on Github
>>>>>>>> <https://github.com/apple/swift-evolution/pull/705/files>.
>>>>>>>>
>>>>>>>> Thanks!
>>>>>>>>
>>>>>>>> ~Robert Widmann
>>>>>>>>
>>>>>>>> Deprecate Tuple Shuffles
>>>>>>>>
>>>>>>>>    - Proposal: SE-NNNN
>>>>>>>>    <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md>
>>>>>>>>    - Authors: Robert Widmann <https://github.com/codafi>
>>>>>>>>    - Review Manager: TBD
>>>>>>>>    - Status: Awaiting review
>>>>>>>>
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction>
>>>>>>>> Introduction
>>>>>>>>
>>>>>>>> This proposal seeks the deprecation of a little-known feature of
>>>>>>>> Swift called a "Tuple Shuffle".
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#motivation>
>>>>>>>> Motivation
>>>>>>>>
>>>>>>>> A tuple-shuffle is an undocumented feature of Swift in which one
>>>>>>>> can re-order the indices of a tuple by writing a pattern that describes a
>>>>>>>> permutation in a syntax reminiscent of adding type-annotations to a
>>>>>>>> parameter list:
>>>>>>>>
>>>>>>>> let a = (x: 1, y: 2)var b: (y: Int, x: Int)
>>>>>>>> b = a
>>>>>>>>
>>>>>>>> It can be used to simultaneously destructure and reorder a tuple:
>>>>>>>>
>>>>>>>> let tuple = (first: 0, second: (x: 1, y: 2))let (second: (x: b, y: c), first: a) = tuple
>>>>>>>>
>>>>>>>> It can also be used to map parameter labels out of order in a call
>>>>>>>> expression:
>>>>>>>>
>>>>>>>> func foo(_ : (x : Int, y : Int)) {}foo((y: 5, x: 10)) // Valid
>>>>>>>>
>>>>>>>> Note that a tuple shuffle is distinct from a re-assignment through
>>>>>>>> a tuple pattern. For example, this series of statements will continue to
>>>>>>>> function as before:
>>>>>>>>
>>>>>>>> var x = 5var y = 10var z = 15
>>>>>>>> (z, y, x) = (x, z, y)
>>>>>>>>
>>>>>>>> Their inclusion in the language complicates every part of the
>>>>>>>> compiler stack, uses a syntax that can be confused for type
>>>>>>>> annotations <https://twitter.com/CodaFi_/status/860246169854894081>,
>>>>>>>> contradicts the goals of earlier SE's (see SE-0060
>>>>>>>> <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md>),
>>>>>>>> and makes non-sensical patterns possible in surprising places.
>>>>>>>>
>>>>>>>> Take switch-statements, for example:
>>>>>>>>
>>>>>>>> switch ((0, 0), 0){ case (_ : let (y, z), _ : let s): () // We are forbidden from giving these patterns names other than "_" default: ()
>>>>>>>> }
>>>>>>>>
>>>>>>>> This proposal seeks to deprecate them in Swift 3 compatibility mode
>>>>>>>> and enforce that deprecation as a hard error in Swift 4 to facilitate their
>>>>>>>> eventual removal from the language.
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#proposed-solution>Proposed
>>>>>>>> solution
>>>>>>>>
>>>>>>>> Construction of Tuple Shuffle Expressions will become a warning in
>>>>>>>> Swift 3 compatibility mode and will be a hard-error in Swift 4.
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#detailed-design>Detailed
>>>>>>>> design
>>>>>>>>
>>>>>>>> In addition to the necessary diagnostics, the grammar will be
>>>>>>>> ammended to simplify the following productions:
>>>>>>>>
>>>>>>>> tuple-pattern → (tuple-pattern-element-list <opt>)
>>>>>>>> tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , tuple-pattern-element-list- tuple-pattern-element → pattern | identifier:pattern+ tuple-pattern-element → pattern
>>>>>>>>
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#impact-on-existing-code>Impact
>>>>>>>> on Existing Code
>>>>>>>>
>>>>>>>> Because very little code is intentionally using Tuple Shuffles,
>>>>>>>> impact on existing code will be negligible but not non-zero.
>>>>>>>>
>>>>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#alternatives-considered>Alternatives
>>>>>>>> considered
>>>>>>>> Continue to keep the architecture in place to facilitate this
>>>>>>>> feature.
>>>>>>>> _______________________________________________
>>>>>>>> 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/20170505/18532a72/attachment.html>


More information about the swift-evolution mailing list