Proposal: Remove implicit tuple splat behavior from function applications


(Michael Henson) #1

After splatting is removed, what will happen in cases where function
arguments are implicitly converted to tuples, as in this code (in the
repl)?

  3> func compose<A,B,C>(f:(A)->B, g:(B)->C) -> (A)->C {
  4. return { (_ arg: A) in
  5. return g(f(arg))
  6. }
  7. }
  8>
  9>
10> func f(a: Int, b: String) -> String {
11. return "Composed!"
12. }
13>
14> func g(x: String) -> Int {
15. return x.characters.count
16. }
17>
18> let c = compose(f, g:g)
c: (Int, b: String) -> Int = 0x00007ffff7ff28d0
19>
20> c
$R0: (Int, b: String) -> Int = 0x00007ffff7ff28d0
21>
22> c((9,b:"Wat"))
$R1: Int = 9
23>
24> c(9, b:"Wat")
repl.swift:24:8: error: extra argument 'b' in call
c(9, b:"Wat")
       ^~~~~

Mike

···

* On Jan 31, 2016, at 5:00 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:

*> >* +1 in general, though I do wonder how this change will affect
generic code. For example, if I have a function that returns a tuple,
and another function that takes an argument list matching the same
tuple type, can I still use generic functions like map() to call the
second function with the tuple from the first? I'm hoping the answer
is "yes", because the type of a function doesn't distinguish between
functions that take multiple arguments vs functions that take a single
argument of tuple type and so passing functions around as first-class
values should be fine. Although I imagine this change will still
prevent me from writing a closure like { funcOfTwoArgs($0) } which is
unfortunate, but would be solved by a subsequent proposal to add an
explicit splat operator.
*
Yes, AFAIK, generic code isn’t affected by the proposed change. Type
checking of generic code is modular, not aware of the concrete types
the generic is instantiated with.

-Chris