[swift-evolution] [Discussion] func/closure parameters and tuples

Vladimir.S svabox at gmail.com
Wed Jun 22 06:54:17 CDT 2016


Even more 'stranges' :

typealias BinaryIntOp_v1 = (Int, Int) -> Int
typealias BinaryIntOp_v2 = ((Int, Int)) -> Int

print(BinaryIntOp_v2.self) // Prints ((Int, Int)) -> Int  why?
print(BinaryIntOp_v2.self) // Prints ((Int, Int)) -> Int

let areRepresentingTheSameType = BinaryIntOp_v1.self == BinaryIntOp_v2.self 
// (alt-click the "==" and read doc.)
print(areRepresentingTheSameType) // Prints true

let add_v1: BinaryIntOp_v1 = (+)
let add_v2: BinaryIntOp_v2 = (+) // Or both could have been eg: { return $0 
+ $1 }

let ra = add_v1(1, 2)
let rb = add_v2((1, 2)) // NOTE: Needs these extra parens (otherwise error: 
"Extra argument in call")

let rc = (add_v1 as BinaryIntOp_v2)((1, 2)) // NOTE: I am type casting 
these to an identical type ...
let rd = (add_v2 as BinaryIntOp_v1)(1, 2)   // ... in order to swap which 
one of them need extra parens ...


I believe we should fix this inconsistency before Swift 3.0 is released as 
this could be source-breaking changes. Opinions?


On 21.06.2016 21:28, Vladimir.S wrote:
> I wanted to ask if the below behavior of compiler/parser is bug or it is
> 'feature' and 'by design' and we will not change this :
>
> 1. I was not expecting this will compile :
>
> let ft1 : (Int,Int) -> Void = { x in print(x.0, x.1)}
>
> ft1(1, 2)
>
> the type of ft1 is definitely not the same as closure
>
>
> 2. The same. But this crashes compiler at compile time(if I understand
> correctly) :
>
> let ft2 : (Int,Int) -> Void = { x in print(x) }
>
> ft2(1, 2)
>
> ----------
> Unhandled conversion from exploded tuple
> ...
> ...
> 1.    While emitting reabstraction thunk in SIL function
> @_TTRXFo_iP___XFo_dSidSi__<unknown>:0: error: unable to execute command:
> Aborted
> <unknown>:0: error: compile command failed due to signal (use -v to see
> invocation)
> ----------
>
>
> 3. Was expecting closure will require a single argument, which is tuple;
> but it accepts even just x, y
>
> typealias IntInt = (Int,Int)
>
> func foo(block: (IntInt) -> Void) {
>     let z : IntInt = (1,2)
>     block(z)
> }
>
> foo { x in print(x)} // ok
> foo { x, y in print(x,y)}
> foo { (x, y) in print(x, y)}
>
> I'm not sending two values to closure, I send one instance which is tuple.
>
>
> Shouldn't we add consistency in Swift regarding allowed argumets of closure
> if tuple is required as parameter?


More information about the swift-evolution mailing list