[swift-evolution] [Pitch] Tuple Destructuring in Parameter Lists

Callionica (Swift) swift-callionica at callionica.com
Mon May 30 18:47:47 CDT 2016


This is an interesting proposal, but I think splatting like Python would be
preferable: creators of functions use separate parameters and callers can
expand tuples as necessary by prefixing a tuple at point of use with * to
expand it into separate arguments.

Even with the Swift language as it is today, it looks like the right thing
to do when you want named pieces of data is to define separate parameters
(or fall back to using a tuple parameter with named components if that's
really impossible).

Erica points out that you can do a lot with the current language. I did
some experiments to see what's possible and it's really easy to enhance
Swift to make it possible to pass tuples to functions expecting separate
parameters. There are a couple of interesting ops that can go into a
library to make things easier:
1. Anonymize a tuple
2. Wrap a function that takes separate arguments with one that takes a tuple

The downside to doing it in a library instead of the compiler is that you
have to splat the function instead of the tuple.

If you have a function 'fn' that takes separate arguments and a tuple 't'
that matches the arguments, you could call it like
(*fn)(t)
instead of
fn(*t)

That's not so bad if one tuple contains all the arguments

You can see experiments at
https://gist.github.com/callionica/43f79dd0a9b145746d72e8a8a62c2820
and I will probably write something about this at
http://www.callionica.com/developer/#swift-splat
at some point

-- Callionica

On Mon, May 30, 2016 at 2:09 PM, Erica Sadun via swift-evolution <
swift-evolution at swift.org> wrote:

>
> On May 30, 2016, at 2:39 PM, Chris Lattner via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> On May 30, 2016, at 6:01 AM, Brent Royal-Gordon via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> // Proposed syntax:
> func takes(a (valueA, valueB): (Int, Int)) {
> // use valueA
> // use valueB
> }
>
>
> FWIW, Swift 1 supported tuple destructuring in parameter lists, and we
> took it out to simplify the language and eliminate special cases.  Whereas
> as a very early version of swift modeled parameter lists using patterns
> (something very common in functional programming languages) we have
> progressively and intentionally move away from that approach.
>
> -Chris
>
>
> You can't splat but you *can* decompose a tuple by assignment:
>
> let a = (1, 2, 3)
> func foo(v1: Int, v2: Int, v3: Int) { print (v1, v2, v3) }
>
> // Still works:
> let (b, c, d) = a; print(b, c, d)
>
> // And this works after the assignment:
> foo(v1: b, v2: c, v3: d)
>
> // No longer works:
> foo(a) // tuple splat is gone
>
> // These all work though:
> func bar(arg: (Int, Int, Int)) { print(arg.0, arg.1, arg.2) }
> bar(arg: a)
> bar(arg: (b, c, d))
>
> // You can add field names in the func's decl type
> func blort(arg: (x: Int, y: Int, z: Int)) { print(arg.x, arg.y, arg.z) }
> blort(arg: a) // works
> blort(arg: (b, c, d)) // works
>
> // But the following doesn't work, Error is "cannot
> // convert value of (l: Int, m: Int, n: Int)"
> blort(arg: (l: b, m: c, n: d))
>
> I vaguely remember a discussion onlist about creating typealiases and then
> using casting to convert between structurally identical tuples but I don't
> think it went anywhere or had a strong use case.
>
> -- E
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160530/1e80ee62/attachment.html>


More information about the swift-evolution mailing list