# SE-0309: Unlock existential types for all protocols

**URL:** <https://forums.swift.org/t/se-0309-unlock-existential-types-for-all-protocols/47515>\
**Category:** Proposal Reviews\
**Created:** [April 17, 2021, 7:56pm UTC](https://forums.swift.org/t/se-0309-unlock-existential-types-for-all-protocols/47515 "2021-04-17T19:56:29Z")\
**Posts on this page:** 1\
**Showing post:** 71

<div class="post-metadata">

**Author:** ![filip-sakel](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/filip-sakel/32/8697_2.png) [@filip-sakel](https://forums.swift.org/u/filip-sakel)\
**Post date:** [April 28, 2021, 6:41pm UTC](https://forums.swift.org/t/se-0309-unlock-existential-types-for-all-protocols/47515/71 "2021-04-28T18:41:01Z")

</div>

> [@1oo7](#):
>
> The Swift style guide says that protocols should have a name that makes it clearly a protocol—an adjective or gerundive describing the capability or behavior represented by the protocol requirement: `Hashable` , `Comparable` , etc. This is not compiler-enforced syntax, but there is seldom any confusion about what is a protocol and what isn't.

OK.

> [@1oo7](#):
>
> Existing Swift gives constraints an explicit syntax; it's clear they are not the same thing as using a protocol as a type. Consider:
> 
> ```swift
> protocol Processable {}
> protocol Usable {}
> func process<T: Processable>(_ item: T) -> Usable 
> 
> ```
> 
> `Processable` is being used as a constraint, and `Usable` is not. It's not ambiguous.

Many Swift users don't know the difference between `func f<T: P>(parameter: T)` and `func f(parameter: P)` — I too was one of those people at some point. The confusion stems from the lack of an indication that `parameter ` is bound to the existential type of `P`; `any P` should hopefully change that.

> [@1oo7](#):
>
> That's more ambiguous, not less, because now it makes sound like `Usable` is a constraint on `any` type that gets returned by the function, just like `View` is a constraint on `some View` that gets returned by a SwiftUI body. However this function won't return just "any" concrete type that conforms to `Usable` , it will always return the same exact type: `Usable` (the existential).

Do you mean that users could perhaps conflate `() -> any Usable` and `<^T: Usable>() -> T` — the latter syntax is borrowed from [`here`](https://forums.swift.org/t/reverse-generics-and-opaque-result-types/21608)?

To me, the `any`-`some` distinction, between existentials and generics respectively, makes sense. Namely, `some Hashable` indicates that a value of **some** (a singular, specific) `Hashable`-conforming type will be returned. On the contrary, `any Hashable` indicates that **any** (an unspecified type, not always the same) `Hashable`-conforming type can be returned (and wrapped in the existential), meaning we can do this: `(Bool.random() ? "" ? 0) as any Hashable` but can't do the same with `some`.

> [@1oo7](#):
>
> I agree it's confusingly worded, but it's not a paradox. There are other ways to explain this, where it makes perfect sense.

That was metaphorical, but unfortunate wording on our part, nonetheless.

> [@1oo7](#):
>
> I don't think syntax "tempts" people. It's just syntax. We should avoid the temptation to use syntax to prescribe behaviors.

I disagree. Syntactic friction can encourage certain styles and discourage others; for example, requiring that existentials be written out as `ThisIsAnExistentialOfProtocol<Hashable>` would result in many preferring `<T: Hashable> T` where possible, choosing the path of least resistance.

> [@1oo7](#):
>
> If we are seeing people avoiding using certain language features, or being confused by them, I think it means we could do a better job of documenting the language & educating Swift developers about how the compiler and runtime work. I'd note that @xwu and their team has done a really excellent job of this lately, and as well there's a lot more resources available for learning the intricacies of Swift than there were a few years back.

Documentation can help but it's not enough.

> [@1oo7](#):
>
> By removing many of those errors, your proposal will unblock more people from using these features—no syntax change needed.

To be clear, we don't propose altering the existential syntax; `let a: any Hashable` will be invalid.

> [@1oo7](#):
>
> `var foo: Proto<Fooable>`

Swift tends to avoid abbreviations.

> [@1oo7](#):
>
> - `var foo: Object<Fooable>`
> - `var foo: dynamic Fooable`

I think these would be poor name choices.

> [@1oo7](#):
>
> I like `Object<Fooable>` because it makes it obvious that protocol-type objects will incur reference semantics just like any other object (yes there are some exceptions but they're basically just a compiler optimization when the object is tiny). It also makes it obvious that we're dealing with a concrete type that allows no further generic specialization, and from which no further static type information can be "opened" without dynamic casting or type erasure schemes.

The only benefit I see to `Object<Protocol>` is the fact that it's a concrete type; however, that would be undermined if we enabled `func f(_: Optional<some Hashable>)`. Nevertheless, I don't think naming should be based on implementation details (existentials don't have reference semantics — mutating one doesn't change another), not to mention that many users would think that `Object` is referring solely to classes. (If we use this syntax, then `Array` which isn't backed by value types, should be called `ArrayObject`.)

---

_[View the full topic](https://forums.swift.org/t/se-0309-unlock-existential-types-for-all-protocols/47515)._
