WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Implicitly opened existentials

Available from Swift 5.7

Paul Hudson      @twostraws

SE-0352 allows Swift to call generic functions using a protocol in many situations, which removes a somewhat odd barrier that existed previously.

As an example, here’s a simple generic function that is able to work with any kind of Numeric value:

func double<T: Numeric>(_ number: T) -> T {
    number * 2
}

If we call that directly, e.g. double(5), then the Swift compiler can choose to specialize the function – to effectively create a version that accepts an Int directly, for performance reasons.

However, what SE-0352 does is allow that function to be callable when all we know is that our data conforms to a protocol, like this:

let first = 1
let second = 2.0
let third: Float = 3

let numbers: [any Numeric] = [first, second, third]

for number in numbers {
    print(double(number))
}

Swift calls these existential types: the actual data type you’re using sits inside a box, and when we call methods on that box Swift understands it should implicitly call the method on the data inside the box. SE-0352 extends this same power to function calls too: the number value in our loop is an existential type (a box containing either an Int, Double, or Float), but Swift is able to pass it in to the generic double() function by sending in the value inside the box.

There are limits to what this capable of, and I think they are fairly self explanatory. For example, this kind of code won’t work:

func areEqual<T: Numeric>(_ a: T, _ b: T) -> Bool {
    a == b
}

print(areEqual(numbers[0], numbers[1]))

Swift isn’t able to statically verify (i.e., at compile time) that both values are things that can be compared using ==, so the code simply won’t build.

Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain. The code can be hard to write, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app.

Explore the docs

Sponsor Hacking with Swift and reach the world's largest Swift community!

Other changes in Swift 5.7…

Download all Swift 5.7 changes as a playground Link to Swift 5.7 changes

Browse changes in all Swift versions

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.