Is Implicit Tuple Splat behavior not fully removed?

So Swift 3 removed implicit tuple splat behavior. See here

So this would work pre-Swift 3 but now it no longer works:

func foo(x:Int, y:Int, z:Int) { }
let bar = (1, 2, 3)
foo(bar)

Meaning you can no longer pass a single tuple and have it automatically distribute into multiple parameters.

What I'm confused about is why does this work?

func call<I, O>(function: (I) -> O, params: I) -> O { return function(params)}
func sum(x:Int, y:Int, z:Int) -> Int {
    return x + y + z
}
let x = (1, 2, 3)
call(function: sum, params: x) //returns sum(x) which returns 6

Why does call(function: sum, params: x) compile but when I call sum(x) directly it doesn't compile?

Does Swift only ban implicit tuple splat behavior (but not explicit). Does Swift consider call(function: sum, params: x) to be explicit tuple splat? If so what is the difference between implicit and explicit here?

You are correct: this behavior is an implicit splat and was removed.

However, this was found to cause an unacceptable usability regression, so an exception was made:

5 Likes

Thank you Xiaodi.

Personally, I prefer this. Tuple splat behavior seems very powerful (though I can understand why they wanted it to be removed, it can definitely be abused). So it's nice that tuple splat behavior is still available, but not available directly. (It just feels really hacky to use it indirectly like this.)

1 Like

Because:

1 Like

It is rather super powerful, actually. Consider the common use case:

let x = ((((((((((((((((((((1, 2, 3))))))))))))))))))))
call(function: (((((sum))))), params: ((((x)))))

Compiles fine, as we all need.

4 Likes

"common" :thinking::thinking::thinking:.

5 Likes

That's is one of the most common concerns I hear from Swift programmers, they get lost in a sea of parentheses. We clearly need to put a stop to this ;-)

-Chris

5 Likes

I’m not sure extra parentheses in this example do anything from the type system perspective. If I recall correctly, (x) is parsed as parenthesis expression, not a tuple literal. And single-element tuples are not possible in Swift.

1 Like

It's usable as such, but like the topic of this thread, how it actually works is confusing and unexplained by documentation.

For the most part. :smile_cat:

Just to clarify: Since an exception was made, is tuple splat behavior considered “deprecated”. Is it something we should never use and they were planning on completely banning it, but they postponed it because it broke too much code and they had other higher priorities to implement.

Or are they partially reversing their decision and saying this one exception is an area where tuple splat behavior is acceptable?

Basically I’m just trying to figure out what best practices are. Are we supposed to stay away from all tuple splat or just most?

2 Likes