Introduction of new keyword 'any' for protocol conforming arguments

I'm currently reviewing GRDB code for the next major version, Swift 5.6+, and it just happens that I'm dealing with SE-0335. I look for all protocol uses, add some any, or refactor into generic functions when relevant.

In a few places, I want to expose apis that accept existentials, and I do not convert them to generic functions. And I don't want the compiler to perform such refactoring automatically.

This happens when the user is expected to call those apis with existentials. This happens, for example, when the user is expected to define collections of heterogenous values (collections of existentials).

With Swift 5.6, we have currently:

protocol P { }

func frobnicate1(_ value: any P) { }
func frobnicate2<T: P>(_ value: T) { }

var values: [any P] = []
for value in values {
    // OK
    frobnicate1(value)
    
    // Compiler error
    // Protocol 'P' as a type cannot conform to the protocol itself
    frobnicate2(value)
}

Maybe [Pitch] Implicitly opening existentials will change this. Maybe the compiler will learn to automatically open existentials when a generic function is called.

But I'm not 100% sure, and maybe @Douglas_Gregor will shed some light.


Now, unless my intuition is wrong, I think that the Core Team currently wants the language to migrate to:

// First form
func startTraveling(with transportation: any Drivable) { }

// Second form
func startTraveling(with transportation: some Drivable) { }

In a way, the runtime behavior of our methods would be made explicit.

Clearly, this does not come without friction! Some people just don't care about this level of explicitness.

So maybe your idea, along with implicit existential opening, will allow us to keep naked protocol names eventually :-)

--

EDIT: @itaiferber you were first :-)

2 Likes