Swift Regret: Labeled Tuple Elements

Part of the Swift Regrets series.

Yep. All of them. This one’s probably controversial, cause it’s convenient for returning multiple values, right? -> (x: Double, y: Double), right? The problem is that once you’ve put it in the language, what do you allow?

(1, 2) as (x: Int, y: Int)
(x: 1, y: 2) as (Int, Int)
(x: 1, y: 2) as (a: Int, b: Int)
(x: 1, y: 2) as (y: Int, x: Int)

And that’s without even getting into dynamic casting.

(x: 1, y: 2) as Any as! (y: Int, x: Int)

Do the labels persist at run time? Swift says no, but it means the check/shuffle for mismatched labels goes out the window. But really you can decide all this conversion stuff, and then you still end up here:

let (x: Int, y: Int) = computePoint()

This gives you an error, because it isn’t the syntax for explicit types. It’s for deconstructing a labeled tuple:

let (x: run, y: rise) = computePoint()

Now, this is specifically a problem because we’re using colons for two different things, but still. Even if there’re a few APIs that really benefit from this “sweet spot” between unlabeled tuples and structs, it’s made the language more complicated for everyone. Are they really worth the trouble for both users and implementors? I’m not convinced. But since we started off using tuples to represent argument lists