[Proposal][Discussion] Deprecate Tuple Shuffles

I can't think of a single time when I would need a tuple shuffle but I don't really work with tuples much. It would be great to hear other people's usage of this feature.
I did not know that types could be overloaded with values. That was very surprising to me. Honestly I think that is the issue here. Not sure what can be done about it.

let Int = 5 // works
let Void = "what?" // works.

Very interesting. Could some one clarify, why this is allowed? Isn't this is a bug we want to fix? At least by requiring a tilda like `Int`
And of course, you can't "overload" user defined type:
struct S {}
let S = 10 // Error: invalid redeclaration of ’S'

What version of swift are you using? Could it be a regression?

Welcome to Apple Swift version 3.1 (swiftlang-802.0.51 clang-802.0.41). Type :help for assistance.
   1> struct S {}
   2> let S = 10
S: Int = 10
   3> print(S)
error: repl.swift:3:7: error: ambiguous use of 'S'
print(S)
       ^

xcrun swift -version

Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
Target: x86_64-apple-macosx10.9

func test() {
     let Int = 10 // no errors/warnings
     print(Int) // no errors/warnings

     struct S {}
     let S = 10 <<<< Error: "Definition conflicts with previous value"
}

···

On 05.05.2017 19:38, Jose Cheyo Jimenez wrote:

On May 5, 2017, at 8:34 AM, Vladimir.S <svabox@gmail.com <mailto:svabox@gmail.com>> >> wrote:
On 05.05.2017 6:12, Jose Cheyo Jimenez via swift-evolution wrote:

On May 4, 2017, at 7:14 PM, Robert Widmann via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> <mailto:swift-evolution@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

* Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
* Authors: Robert Widmann <https://github.com/codafi&gt;
* Review Manager: TBD
* Status: Awaiting review

   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;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&gt;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= 5
var y= 10
var 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&gt;, contradicts the goals of earlier SE's (see SE-0060 <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\), 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&gt;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&gt;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&gt;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&gt;Alternatives
   considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Thanks, I just got the point:
  This is a war between Smalltalk and the world.

In Smalltalk, function is not a type:
   function's signature include attributes name, but Type not,.
The method Smalltalk treat function, is opposite to the normal method human
see the world.
For exam:
   We just need known someone called Boris Wang, not Boris
Wang(attr1,attr2,....,attr100)

So, the more features we borrowed from the other languages in the world,
the more conflicts triggered.
The more consistent we wanted from Swift, the more conflicts triggered.

Erica Sadun via swift-evolution <swift-evolution@swift.org>于2017年5月9日
周二02:42写道:

···

On May 4, 2017, at 8:14 PM, Robert Widmann via swift-evolution < > swift-evolution@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

I'm coming into this ridiculously late. Apologies, but I've had family
responsibilities. I've tried to read through the thread before replaying. I
hope I have not missed any significant points.

First, I dislike calling this "tuple shuffles". That phrase has an
existing and useful meaning in the Swift community. It refers to what this
proposal calls "re-assignment through a tuple pattern". This is what I want
to keep calling a "tuple shuffle":

`(a, b, c) = (b, c, a)`

I'd rather call the problem space for this proposal "label-led tuple
assignment" (or something like that) and reserve "tuple shuffle" for
reordered value reassignment.

Second, I agree with TJ. I dislike that this pattern is legal:

// Declare using labels
let rgba: (r: Int, g: Int, b: Int, a: Int) = (255, 255, 255, 0)

// Declare using re-ordered labels
let argb: (a: Int, r: Int, g: Int, b: Int) = rgba // This is the line I
have issue with

print(argb.a) // "0"

I find this usage counter to Swift's philosophy of clarity and simplicity.
It is sufficiently obscure that I consider it a non-standard use regardless
of Wux's Google search results.

Consider the example of Joe Groff's SE-0060 (
https://github.com/apple/swift-evolution/blob/master/proposals/0060-defaulted-parameter-order.md\).
I believe it's reasonable to mandate that the order of labels in
declarations be ignored, with the types being compiler-checked. I'd
envision that the "correct" behavior should act like this instead:

// Declare using re-ordered labels
let argb: (a: Int, r: Int, g: Int, b: Int) = rgba // (Int, Int, Int, Int)
assigned to (Int, Int, Int, Int)

print(argb.a) // "255"

This reworking is partially inspired by SE-0111 (
https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md\),
ensuring that the tuple argument labels are not considered in typing the
new constant. In fact, this entire proposal might be better named "Removing
the Ordering Significance of Tuple Argument Labels in Declarations"

-- E

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

No, I thought this was what Robert was proposing, but he is proposing the
elimination of all labels in tuple patterns. Your second example would be
banned.

···

On Fri, May 5, 2017 at 12:42 AM, Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Okay now I see where this is going. So basically you want to mirror the
behavior of function parameters into tuples.

You might want to be a little bit more explicit on types in your proposal
to better understand the so called ‘tuple shuffle’.

let a: (x: Int, y: Int) = (x: 1, y: 2)
var b: (y: Int, x: Int) = a
a.x == b.x
a.y == b.y

Label swap (tuple shuffle) while destructuring:

let tuple: (first: Int, second: (x: Int, y: Int)) = (first: 0, second: (x: 1, y: 2))

let (first: a, second: (x: b, y: c)): (first: Int, second: (x: Int, y: Int)) = tuple // fine, unaffected

let (second: (x: b, y: c), first: a): (second: (x: Int, y: Int), first: Int) = tuple // shuffle => error

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@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@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@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@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub;
.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;, contradicts
the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Eliminating all labels would mean that even the first example from my last post will be banned.

Is there any difference from labels in tuple types and labels in tuples themselves?

Personally I would not support the removal of labels from tuple types, because it’s a very useful feature that replaces indexed access like myTuple.1 to a more readable counterpart myTuple.somethingSpecial.

Am I still missing something out?

···

--
Adrian Zubarev
Sent with Airmail

Am 5. Mai 2017 um 07:43:49, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Fri, May 5, 2017 at 12:42 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Okay now I see where this is going. So basically you want to mirror the behavior of function parameters into tuples.

You might want to be a little bit more explicit on types in your proposal to better understand the so called ‘tuple shuffle’.

let a: (x: Int, y: Int) = (x: 1, y: 2)
var b: (y: Int, x: Int) = a
a.x == b.x
a.y == b.y
Label swap (tuple shuffle) while destructuring:

let tuple: (first: Int, second: (x: Int, y: Int)) = (first: 0, second: (x: 1, y: 2))

let (first: a, second: (x: b, y: c)): (first: Int, second: (x: Int, y: Int)) = tuple // fine, unaffected

let (second: (x: b, y: c), first: a): (second: (x: Int, y: Int), first: Int) = tuple // shuffle => error

No, I thought this was what Robert was proposing, but he is proposing the elimination of all labels in tuple patterns. Your second example would be banned.

~Robert Widmann

2017/05/05 14:07、John McCall <rjmccall@apple.com> のメッセージ:

- Parse: Has to account for the inclusion of tuple shuffles whenever it parses patterns (see the switch-statement example in the proposal)

This example doesn't make any sense. Tuple shuffles are not responsible for the rule that you cannot match an unlabelled tuple with a labelled tuple pattern. I'm really not sure what you think this would do, anyway; it's not like tuple pattern element labels are lexically available.

Exactly. I've since removed this example. My initial confusion was around the labeled matching being a thing at all.

···

On May 4, 2017, at 10:52 PM, Robert Widmann via swift-evolution <swift-evolution@swift.org> wrote:

- Sema: Has to perform argument matching by computing these tuple shuffle mappings thereby complicating the solver and the parts of solution application. Really, the only place this has a valid use is in the error handling path where we can use the tuple shuffle to emit a fixit that properly reorders arguments - something we should be doing even today. Tuple shuffles are also allowed to reorder around variadic arguments which makes matching that much more difficult.

The type-checker doesn't have to do this with argument-matching. It might do it anyway, but it doesn't have to.

- SIL: Has to account for tuple shuffles in multiple places. One notable one is that SILGen has to support two different paths when lowering tuple shuffles - one for variadic shuffles and the other for “normal” shuffles. Each path supports a different subset of the features necessary to implement the full feature that is tuple shuffles, neither can really be simplified down to a common core in their current iteration.

Call argument emission needs to deal with something like this anyway. But yes, we could eliminate the redundant path for ordinary r-value tuple emission.

I'm not saying any of this to kill this proposal, just to clarify that the complexity costs aren't as high as you seem to be saying.

John.

If you want some numbers, I spent the evening removing them from the codebase and came up with a win of about 1500 LoC. Each line of code supporting a feature that people aren’t actually using.

~Robert Widmann

On May 4, 2017, at 10:35 PM, Tony Arnold via swift-evolution <swift-evolution@swift.org> wrote:

On 5 May 2017, at 12:27, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

Why?

Not trying to be smart, but the reasoning is in Robert’s proposal:

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), and makes non-sensical patterns possible in surprising places.

Robert, maybe you could include some detail about how this feature is complicating the compiler stack, and what will be improved by it’s removal?

====

That being said, I’m all for you guys making your lives easier at the cost of something we shouldn’t be using in the first place…

Tony

----------
Tony Arnold
+61 411 268 532
http://thecocoabots.com/

ABN: 14831833541

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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.

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.

···

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@gmail.com> wrote:

~Robert Widmann

On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;, contradicts
the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Eliminating all labels would mean that even the first example from my last
post will be banned.

No, not eliminating all labels from tuples, but from tuple _patterns_.

···

On Fri, May 5, 2017 at 12:52 AM, Adrian Zubarev < adrian.zubarev@devandartist.com> wrote:

Is there any difference from labels in tuple types and labels in tuples
themselves?

Personally I would not support the removal of labels from tuple types,
because it’s a very useful feature that replaces indexed access like
myTuple.1 to a more readable counterpart myTuple.somethingSpecial.

Am I still missing something out?

--
Adrian Zubarev
Sent with Airmail

Am 5. Mai 2017 um 07:43:49, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Fri, May 5, 2017 at 12:42 AM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

Okay now I see where this is going. So basically you want to mirror the
behavior of function parameters into tuples.

You might want to be a little bit more explicit on types in your proposal
to better understand the so called ‘tuple shuffle’.

let a: (x: Int, y: Int) = (x: 1, y: 2)
var b: (y: Int, x: Int) = a
a.x == b.x
a.y == b.y

Label swap (tuple shuffle) while destructuring:

let tuple: (first: Int, second: (x: Int, y: Int)) = (first: 0, second: (x: 1, y: 2))

let (first: a, second: (x: b, y: c)): (first: Int, second: (x: Int, y: Int)) = tuple // fine, unaffected

let (second: (x: b, y: c), first: a): (second: (x: Int, y: Int), first: Int) = tuple // shuffle => error

No, I thought this was what Robert was proposing, but he is proposing the
elimination of all labels in tuple patterns. Your second example would be
banned.

I should add, it boggles the mind that you would claim that people will
have never heard of this before today. It's been discussed _on this very
list_!

···

On Fri, May 5, 2017 at 12:42 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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.

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.

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.

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

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.

···

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

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@gmail.com> > wrote:

~Robert Widmann

On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;, contradicts
the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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

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.

~Robert Widmann

···

On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu@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@gmail.com <mailto:xiaodi.wu@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@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

Proposal: SE-NNNN <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
Authors: Robert Widmann <https://github.com/codafi&gt;
Review Manager: TBD
Status: Awaiting review
<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;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&gt;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 = 5
var y = 10
var 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&gt;, contradicts the goals of earlier SE's (see SE-0060 <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\), 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&gt;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&gt;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&gt;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&gt;Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

Enum cases are a different kettle of fish since the last round of proposals

···

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

(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@gmail.com> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;,
contradicts the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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

···

On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

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

(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@gmail.com> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;,
contradicts the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this
feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

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.

···

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@gmail.com> wrote:

~Robert Widmann

On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu@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@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@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@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@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.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles
Proposal: SE-NNNN
Authors: Robert Widmann
Review Manager: TBD
Status: Awaiting review
Introduction

This proposal seeks the deprecation of a little-known feature of Swift called a "Tuple Shuffle".

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 = 5
var y = 10
var 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, contradicts the goals of earlier SE's (see SE-0060), 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.

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.

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
Impact on Existing Code

Because very little code is intentionally using Tuple Shuffles, impact on existing code will be negligible but not non-zero.

Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

···

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

~Robert Widmann

On May 5, 2017, at 2:35 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:21 AM, Robert Widmann <devteam.codafi@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@gmail.com> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;,
contradicts the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this
feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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@gmail.com> のメッセージ:

···

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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@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@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@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@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@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.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles
Proposal: SE-NNNN
Authors: Robert Widmann
Review Manager: TBD
Status: Awaiting review
Introduction

This proposal seeks the deprecation of a little-known feature of Swift called a "Tuple Shuffle".

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 = 5
var y = 10
var 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, contradicts the goals of earlier SE's (see SE-0060), 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.

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.

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
Impact on Existing Code

Because very little code is intentionally using Tuple Shuffles, impact on existing code will be negligible but not non-zero.

Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

I should add, there's an added benefit here. If you allow labels but remove
shuffling, there's a good chance that *unintentional* shuffles get called
out during migration. Boom, bugs fixed, better code. Swift saves the day.

···

On Fri, May 5, 2017 at 2:14 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

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

~Robert Widmann

On May 5, 2017, at 2:35 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:21 AM, Robert Widmann <devteam.codafi@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@gmail.com> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@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@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@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@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@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@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
<[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

   - Proposal: SE-NNNN
   <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
   - Authors: Robert Widmann <https://github.com/codafi&gt;
   - Review Manager: TBD
   - Status: Awaiting review

<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;
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&gt;
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&gt;,
contradicts the goals of earlier SE's (see SE-0060
<https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\),
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&gt;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&gt;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&gt;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&gt;Alternatives
considered
Continue to keep the architecture in place to facilitate this
feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

~Robert Widmann

···

On May 5, 2017, at 2:35 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Fri, May 5, 2017 at 1:21 AM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@gmail.com>> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@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@gmail.com <mailto:xiaodi.wu@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@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

Proposal: SE-NNNN <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
Authors: Robert Widmann <https://github.com/codafi&gt;
Review Manager: TBD
Status: Awaiting review
<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;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&gt;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 = 5
var y = 10
var 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&gt;, contradicts the goals of earlier SE's (see SE-0060 <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\), 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&gt;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&gt;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&gt;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&gt;Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

What others have noted, in addition to our Twitter thread, is that this proposal has revealed the need for diagnostics about shadowing. There are currently two boundaries in Swift along which we allow shadowing in the same scope: Function arguments and patterns. If we can close both of those loopholes I would be much less skittish about labels.

~Robert Widmann

···

On May 5, 2017, at 2:35 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, May 5, 2017 at 1:31 AM, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
On Fri, May 5, 2017 at 1:21 AM, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@gmail.com>> のメッセージ:

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

~Robert Widmann

2017/05/05 1:42、Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> のメッセージ:

On Fri, May 5, 2017 at 00:17 Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@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@gmail.com <mailto:xiaodi.wu@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@gmail.com <mailto:devteam.codafi@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@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@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 <[Proposal] Deprecate Tuple Shuffle Expressions by CodaFi · Pull Request #705 · apple/swift-evolution · GitHub.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

Proposal: SE-NNNN <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-filename.md&gt;
Authors: Robert Widmann <https://github.com/codafi&gt;
Review Manager: TBD
Status: Awaiting review
<https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/NNNN-deprecate-tuple-shuffles.md#introduction&gt;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&gt;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 = 5
var y = 10
var 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&gt;, contradicts the goals of earlier SE's (see SE-0060 <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md&gt;\), 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&gt;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&gt;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&gt;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&gt;Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

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

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.

For what it's worth, I thought I knew Swift inside out and I had never seen or used the syntax your are proposing to ban, so I'm all for it.

···

On 5 May 2017, at 07:17, Robert Widmann via swift-evolution <swift-evolution@swift.org> wrote:

~Robert Widmann

On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi.wu@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@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@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@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@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.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles
Proposal: SE-NNNN
Authors: Robert Widmann
Review Manager: TBD
Status: Awaiting review
Introduction

This proposal seeks the deprecation of a little-known feature of Swift called a "Tuple Shuffle".

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 = 5
var y = 10
var 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, contradicts the goals of earlier SE's (see SE-0060), 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.

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.

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
Impact on Existing Code

Because very little code is intentionally using Tuple Shuffles, impact on existing code will be negligible but not non-zero.

Alternatives considered

Continue to keep the architecture in place to facilitate this feature.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution