# \[Pitch\] Introduce existential \`any\`

**URL:** <https://forums.swift.org/t/pitch-introduce-existential-any/53520>\
**Category:** Pitches\
**Created:** [November 16, 2021, 3:48am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520 "2021-11-16T03:48:13Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [November 16, 2021, 3:48am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/1 "2021-11-16T03:48:13Z")

</div>

Hello Swift Evolution!

I recently started a discussion about [easing the learning curve of introducing generic parameters](https://forums.swift.org/t/discussion-easing-the-learning-curve-for-introducing-generic-parameters/52891). In that discussion, it was brought up multiple times that the existing syntax of existential types is actively harmful, and we should consider making the implications explicit in the language. I wrote up a proposal for introducing an `any` keyword for this purpose.

I've pasted the first iteration of the proposal below, and you can view the latest version here: [swift-evolution/proposals/NNNN-existential-any.md at existential-any · hborla/swift-evolution · GitHub](https://github.com/hborla/swift-evolution/blob/existential-any/proposals/NNNN-existential-any.md)

Please let me know your questions, thoughts, and other constructive feedback!

-Holly

* * *

## Introduction

Existential types in Swift have an extremely lightweight spelling: a plain protocol name in type context means an existential type. Over the years, this has risen to the level of **active harm** by causing confusion, leading programmers down the wrong path that often requires them to re-write code once they hit a fundamental [limitation of value-level abstraction](https://forums.swift.org/t/improving-the-ui-of-generics/22814#heading--limits-of-existentials). This proposal makes the impact of existential types explicit in the language by annotating such types with `any`.

## Motivation

Existential types in Swift have significant limitations and performance implications. Some of their limitations are missing language features, but many are fundamental to their type-erasing semantics. For example, given a protocol with associated type requirements, the existential type cannot conform to the protocol itself without a manual conformance implementation, because there is not an obvious concrete associated type that works for any value conforming to the protocol, as shown by the following example:

```swift
protocol P {
  associatedtype A
  func test(a: A)
}

func generic<ConcreteP: P>(p: ConcreteP, value: ConcreteP.A) {
  p.test(a: value)
}

func useExistential(p: P) {
  generic(p: p, value: ???) // what type of value would P.A be??
}

```

Existential types are also significantly more expensive than using concrete types. Because they can store any value whose type conforms to the protocol, and the type of value stored can change dynamically, existential types require dynamic memory unless the value is small enough to fit within an inline 3-word buffer. In addition to heap allocation and reference counting, code using existential types incurs pointer indirection and dynamic method dispatch that cannot be optimized away.

Despite these significant and often undesirable implications, existential types have a minimal spelling. Syntactically, the cost of using one is hidden, and the similar spelling to generic constraints has caused many programmers to confuse existential types with generics. In reality, the need for the dynamism they provided is relatively rare compared to the need for generics, but the language makes existential types too easy to reach for, especially by mistake. The cost of using existential types should not be hidden, and programmers should explicitly opt into these semantics.

## Proposed solution

I propose to make existential types syntactically explicit in the language using the `any` keyword. This proposal introduces the new syntax, and this syntax should be required under the Swift 6 language mode.

## Detailed design

### Grammar of explicit existential types

This proposal adds the following production rules to the grammar of types:

```swift
type -> existential-type

existential-type -> 'any' type

```

### Semantics of explicit existential types

The semantics of `any` types are the same as existential types today. Explicit `any` can only be applied to protocols and protocol compositions; `any` cannot be applied to nominal types, structural types, and type parameters:

```swift
struct S {}

let s: any S = S() // error: 'any' has no effect on concrete type 'S'

func generic<T>(t: T) {
  let x: any T = t // error: 'any' has no effect on type parameter 'T'
}

```

`any` also cannot be applied to `Any` and `AnyObject` (unless part of a protocol composition).

> Rationale: `any Any` and `any AnyObject` are redundant. `Any` and `AnyObject` are already special types in the language, and their existence isn’t nearly as harmful as existential types for regular protocols because the type-erasing semantics is already explicit in the name.

The existential metatype becomes `(any P).Type`, and the protocol metatype remains `P.Protocol`.

Examples

```swift
protocol P {}
class C {}

any P
any Any // error
any AnyObject // error
any P & AnyObject
any C // error
any P & C
any () -> Void // error
(any P).Type

func test<T>(_: T) where T == any P

```

## Source compatibility

Enforcing that existential types use the `any` keyword will require a source change. To ease the migration, I propose to start allowing existential types to be spelled with `any` with the Swift 5.6 compiler, and require existential types to be spelled with `any` under the Swift 6 language mode. The old existential type syntax will continue to be supported under the Swift 5 language mode, and the transition to the new syntax is mechanical, so it can be performed automatically by a migrator.

[SE-0306 Unlock existentials for all protocols](https://github.com/apple/swift-evolution/blob/main/proposals/0309-unlock-existential-types-for-all-protocols.md) enables more code to be written using existential types. To minimize the amount of new code written that will become invalid in Swift 6, I propose requiring `any` immediately for protocols with `Self` and associated type requirements. This introduces an inconsistency for protocols under the Swift 5 language mode, but this inconsistency already exists today (because you cannot use certain protocols as existential types at all), and the syntax difference serves two purposes:

1. It saves programmers time in the long run by preventing them from writing new code that will become invalid later.
2. It communicates the existence of `any` and encourages programmers to start using it for other existential types before adopting Swift 6.

## Effect on ABI stability

None.

## Effect on API resilience

None.

## Alternatives considered

Instead of leaving `Any` and `AnyObject` in their existing spelling, an alternative is to spell these types as `any Value` and `any Object`, respectively. Though this is more consistent with the rest of the proposal, this change would have an even bigger source compatibility impact. Given that `Any` and `AnyObject` aren’t as harmful as other existential types, changing the spelling isn’t worth the churn.

## Future Directions

### Extending existential types

This proposal provides an obvious syntax for extending existential types in order to manually implement protocol conformances:

```swift
extension any Equatable: Equatable { ... }

```

### Re-purposing the plain protocol name

In other places in the language, a plain protocol name is already sugar for a type parameter conforming to the protocol. Consider a normal protocol extension:

```swift
extension Collection { ... }

```

This extension is a form of universal quantification; it extends all types that conform to `Collection`. This extension introduces a generic context with a type parameter `<Self: Collection>`, which means the above syntax is effectively sugar for a parameterized extension:

```swift
extension <Self> Self where Self: Collection { ... }

```

Changing the syntax of existential types creates an opportunity to expand upon this sugar. If existential types are spelled explicitly with `any`, a plain protocol name could always mean sugar for a type parameter on the enclosing context with a conformance requirement to the protocol. For example, consider the declaration of `append(contentsOf:)` from the standard library:

```swift
extension Array {
  mutating func append<S: Sequence>(contentsOf newElements: S) where S.Element == Element
}

```

Combined with a syntax for constraining associated types in angle brackets, such as in [[Pitch] Light-weight same-type constraint syntax](https://forums.swift.org/t/pitch-light-weight-same-type-constraint-syntax/52889), the above declaration could be simplified to:

```swift
extension Array {
  mutating func append(contentsOf newElements: Sequence<Element>)
}

```

This sugar eliminates a lot of noise in cases where a type parameter is only referred to once in a generic signature, and it enforces a natural model of abstraction, where programmers only need to name an entity when they need to refer to it multiple times.

## Acknowledgments

Thank you to Joe Groff, who originally suggested this direction and syntax in [Improving the UI of generics](https://forums.swift.org/t/improving-the-ui-of-generics/22814), and to those who advocated for this change in the recent discussion about [easing the learning curve for generics](https://forums.swift.org/t/discussion-easing-the-learning-curve-for-introducing-generic-parameters/52891).

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [November 16, 2021, 4:19am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/2 "2021-11-16T04:19:19Z")

</div>

I haven't yet thought through all of the implications, but I think the proposal could use a section which compares the Swift 5 and 6 language modes with this feature. If I understand this correctly, it makes naked use of an existential type a compiler error, requiring `any Existential` instead. Perhaps the "Proposed solution" section could summarize the change?

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [November 16, 2021, 4:19am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/3 "2021-11-16T04:19:54Z")

</div>

Thrilled to see `any` get a proper pitch, it will be interesting to see how the community feels about the tradeoffs of a source break here. This will require a _lot_ of code churn, but it will hopefully be an easy migration and worth it in the long run.

I’m sure I’ll have more to say once I’ve had a chance to think through everything a bit more, but just wanted to say:

> [@hborla](#):
>
> The existential metatype becomes `(any P).Type` , and the protocol metatype remains `P.Protocol` .

Perhaps it’s come up before in discussions of `any`, but this clarification of the confusing `P.Type` vs `P.Protocol` situation is a nice little bonus win for deprecating bare existential syntax that I hadn’t considered previously. 🙂

---

<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:** [November 16, 2021, 5:02am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/4 "2021-11-16T05:02:37Z")

</div>

I’m also really excited and will be glad if the proposal is accepted and implemented before SE309 is rolled out.

One question: how would one write ‘[Any]’ with the new syntax since ‘any Any’ is prohibited?

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [November 16, 2021, 5:31am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/5 "2021-11-16T05:31:49Z")

</div>

I assume it'll be the same as with `some` types, but might be good to call out precedence rules (e.g., requiring parens to spell `(any P)?`, which admittedly is much wordier than `P?`).

> [@hborla](#):
>
> `any` also cannot be applied to `Any` and `AnyObject` (unless part of a protocol composition).
> 
> > Rationale: `any Any` and `any AnyObject` are redundant. `Any` and `AnyObject` are already special types in the language, and their existence isn’t nearly as harmful as existential types for regular protocols because the type-erasing semantics is already explicit in the name.

I see the rationale in not _requiring_ `any` for these, but I don't see the harm that necessitates a special rule to _ban_ them. It's visually redundant but certainly not confusing, and it'd be nice not to have errors pop up midway through writing a protocol composition that begins `any AnyObject & ...`.

> [@filip-sakel](#):
>
> One question: how would one write ‘[Any]’ with the new syntax since ‘any Any’ is prohibited?

Wouldn't that just remain `[Any]`?

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [November 16, 2021, 5:34am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/6 "2021-11-16T05:34:23Z")

</div>

> [@hborla](#):
>
> the transition to the new syntax is mechanical, so it can be performed automatically by a migrator.

That must mean that the `as Protocol`s turn into `as any Protocol`s, yes?

If so, we can't reasonably have support for `as any` without [`as some`](https://forums.swift.org/t/se-0328-structural-opaque-result-types/53248/8) as well. If the latter comes along with the former, this is a doubly great pitch.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [November 16, 2021, 5:58am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/7 "2021-11-16T05:58:09Z")

</div>

I’m extremely in favor of this, thank you for making it happen! I want to offer one suggestion: allow `any P.Type`. That’s easier to type, obviously, but I’ll argue there’s a semantic reason as well. This type serves two purposes: it’s both the result of `type(of: someExistentialValue)`, _and_ it’s the type that has the operations marked `static` in the protocol. In that sense, today’s `P.Type` is an existential type as well, not merely the metatype for an existential type. An API that has a parameter of type `P.Type` probably has arguments that look like `NSObject.self`, not the type of an existing instance. In another language, `P.Type` could be a protocol that `NSObject.Type` conforms to. That means a hypothetical `any (P.Type)` is a reasonable type, which also happens to be the same type, in Swift, as `(any P).Type`. Which works out nicely!

Now, if only I could convince myself the same applies to `any P?`…

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [November 16, 2021, 5:59am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/8 "2021-11-16T05:59:04Z")

</div>

Unrelatedly: the Rust discussion about their own change in this vein: [`dyn Trait` Syntax for Trait Objects: Take 2 by Ixrec · Pull Request #2113 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/2113)

---

<div class="post-metadata">

**Author:** ![Dmitriy\_Ignatyev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dmitriy_ignatyev/32/11340_2.png) [@Dmitriy\_Ignatyev](https://forums.swift.org/u/Dmitriy_Ignatyev)\
**Post date:** [November 16, 2021, 6:50am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/9 "2021-11-16T06:50:45Z")

</div>

Hi, very excited about this changes, thanks for summarizing all the points.  
Just one question: how self-conforming protocols will be expressed?

```swift
let error: Error = NetworkError() // or `let error: any Error = ...` ?

generic(error)

func generic<SomeError: Error>(error: SomeError) {
  let errorCopy: SomeError // or `let errorCopy: any SomeError` if argument of Error existential type is passed?
}

```

---

<div class="post-metadata">

**Author:** ![ExFalsoQuodlibet](https://avatars.discourse-cdn.com/v4/letter/e/bbce88/32.png) [@ExFalsoQuodlibet](https://forums.swift.org/u/ExFalsoQuodlibet)\
**Post date:** [November 16, 2021, 9:49am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/10 "2021-11-16T09:49:00Z")

</div>

Huge +1 on this, I'm so glad it's getting a pitch.

---

<div class="post-metadata">

**Author:** ![duan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/duan/32/40252_2.png) [@duan](https://forums.swift.org/u/duan)\
**Post date:** [November 16, 2021, 9:52am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/11 "2021-11-16T09:52:58Z")

</div>

+1 on the observation that the current syntax causes active harm. I wager a majority of working Swift users never properly learned the concept of existential due to confusion caused by it.

---

<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:** [November 16, 2021, 11:56am UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/12 "2021-11-16T11:56:24Z")

</div>

> [@xwu](#):
>
> Wouldn't that just remain `[Any]` ?

Isn’t `Any` considered an existential here? If so, then `any Any` seems more consistent to me. Yes, it’s not great, but we can introduce `Value` and deprecate `Any` in Swift 6 for a less disruptive source break.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 16, 2021, 12:16pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/13 "2021-11-16T12:16:08Z")

</div>

This is a great proposal and I welcome the introduction of the `any` keyword. There is one thing that I'd like to push for reconsideration. Why is it a requirement to disallow `any S` where `S` a value type or a class, etc.?

Can't `any` not only represent existentials but also sub-types? While `any S` won't have any effect as we don't have sub typing for value types now, `Never` as a bottom type will/could fall under this umbrella in the future. `any C` for a class could already make sense and it would be equivalent to the today's `C`.

```swift
class C {} 
class D: C {}

// today
let c: C = D() // okay
// after the proposal
let anyC: any C = D() // theoretically the same as above

```

I personally think that `some C` would equally make sense where one could express that there is an opaque class involved, especially when we discuss the possibility of the generic footprint reduction via the `some` keyword in a context of generic type parameter `T` constrained by a class type.

```swift
<T: C>(_: T) ---- becomes ----> (_: some C)

```

If there is `some C`, then there should be `any C` as well.

* * *

TLDR; can't we make those errors as warnings instead?

Of course we could relax this rule in the future, but I'd like to know if it would be okay to do it with this proposal already.

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 16, 2021, 12:52pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/14 "2021-11-16T12:52:11Z")

</div>

> [@jrose](#):
>
> I’m extremely in favor of this, thank you for making it happen! I want to offer one suggestion: allow `any P.Type` . That’s easier to type, obviously, but I’ll argue there’s a semantic reason as well. This type serves two purposes: it’s both the result of `type(of: someExistentialValue)` , _and_ it’s the type that has the operations marked `static` in the protocol. In that sense, today’s `P.Type` is an existential type as well, not merely the metatype for an existential type. An API that has a parameter of type `P.Type` probably has arguments that look like `NSObject.self` , not the type of an existing instance. In another language, `P.Type` could be a protocol that `NSObject.Type` conforms to. That means a hypothetical `any (P.Type)` is a reasonable type, which also happens to be the same type, in Swift, as `(any P).Type` . Which works out nicely!
> 
> Now, if only I could convince myself the same applies to `any P?` …

> [@Improving the UI of generics](https://forums.swift.org/t/improving-the-ui-of-generics/22814/149):
>
> With the `any` modifier, there’s an opportunity to revise the current meta type syntax to be more obvious. `P.Protocol` , the type of `P.self` , would be `(any P).Type` , whereas the type of all `T.self` where `T: P` would be `any P.Type` if we say that `P.Type` is a generic constraint for a meta type conforming to P.

I'm also going to bump the ideas regarding the issues with the current metatype spelling. There are meta types which are static and the result of `Type.self` and there are meta type existentials. The current state of the proposal pitch does not cover this whole area, which can be improved with the introduction of the `any` keyword.

* * *

Without derailing the current topic from the `any` keyword, in the UX related thread we also briefly discussed the idea of another keyword named `meta` to improve metatypes. Here's a short explanation of the types it would cover compared against the `any` syntax:

```swift
typealias Meta<T> = meta T

P.Protocol == (any P).Type == Meta<any P> == Meta<P> == meta P
    P.Type == any P.Type == any Meta<P> == any meta P
              ~~~~~~~~~~~~

```

I'm not asking for an additional introduction of that keyword, I just mention it to further clarify what `any` keyword can already cover and why.

This also further emphasis why the `any` keyword should support not only existentials (e.g. protocol conformances) but sub-typing (e.g. inheritance) as well!

---

<div class="post-metadata">

**Author:** ![SwiftUI](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/swiftui/32/24361_2.png) [@SwiftUI](https://forums.swift.org/u/SwiftUI)\
**Post date:** [November 16, 2021, 1:27pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/15 "2021-11-16T13:27:54Z")

</div>

+1 for this very nice proposal.

I like `Any->Value` and `AnyObject->Object` transition, maybe it's time to make this change through 5.6 release.

`Any` protocol means `any value` by literal in Swift, now we have `any P` syntax to support this subtle conception, formalize `Value` and `any Value` would be much better.

IIRC, `AnyObject` naming problem been raised and discussed several times in forum, it should be `Object` by initial design. Now finally we have a chance to fix this problem in this proposal. `any Object` is the right design by nature, and furthermore I really hate `protocol SomeP: AnyObject ` class bound protocol declaration. So weird to look and read~

`any Value/Object` change is the right thing to do, and it's the right time to do this right thing. Please fixing it!

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [November 16, 2021, 2:41pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/16 "2021-11-16T14:41:10Z")

</div>

Heh, perhaps the `(any P).Type` win was not as clear as I initially thought. Between this proposal, @jrose's suggestion that `any P.Type` and `(any P).Type` be the same, and @Joe_Groff's earlier suggestion that `P.Protocol` become `(any P).Type`, we have _three_ different (and incompatible) ideas of how `any` syntax should apply to protocol metatypes. IMO, having `P.Type` become `(any P).Type` makes sense, since to me that syntax naturally reads as "the metatype of all types which conform to `P`", and I'm ambivalent-to-negative on having `any P.Type` mean the same thing. I think I _big_ plus of `(any P).Type` is that it puts some visual distance and a bit of syntactic clarification between the former `P.Type` and `P.Protocol`. If we continued to allow `P.Type` as a syntactic form (even if it were required to prefix with `any`, we'd lose that benefit.

In the same vein, I'd be _strongly_ against allowing both `any P.Type` and `(any P).Type` and having those mean different things. I suspect that would lead to even more confusion than the `Type`-`Protocol` issue we have today.

* * *

On another note, I'd like to discuss a bit more about the source break here. As I mentioned previously, this is going to be a _big_ break if adopted as is. Hopefully it will be as simple as prepending `any` to all existing existential type names, but I do wonder whether there are ways that we could mitigate the amount of churn that will be required.

As came up in a previous thread, some uses of existentials are isomorphic to generics thanks to Swift not requiring monomorphization for generic functions. That is, if we remove the associated type from the proposal's example, there's not a fundamental issue with:

```swift
protocol P {
  func test()
}

func generic<ConcreteP: P>(p: ConcreteP) {
  p.test()
}

func useExistential(p: P) {
  generic(p: p)
}

```

In fact, we can already call `generic` from within `useExistential` today, with `_openExistential`:

```swift
func useExistential(p: P) {
  _openExistential(p) { concrete in
    generic(p: concrete)
  }
}

```

I _suspect_ that we could come up with a reasonable list of non-problematic uses of existentials that maybe don't need to require `any` syntax. In the above situation, we could auto-open the existential so that the `generic(p: p)` call succeeds without any dance.

The proposal also calls out concerns that "the type of value stored can change dynamically" but this is only true insofar as the value can change at all—if the value of existential type is a `let` (as with non-`inout` function parameters), then we needn't worry about the concrete type changing dynamically.

I think we could possibly also get away with allowing bare existentials for `@objc` protocols.

Together with auto-opening of existentials, I do wonder if a rule like the following would get us most (all?) of the benefit while reducing the code churn required:

> An existential type must be annotated with `any` if the protocol is not `@objc` and either of the following is true:
> 
> - The protocol has `Self` or `associatedtype` requirements
> - The value of existential type is mutable

Since SE-0306 hasn't shipped with an official version of Swift yet (right?), that would allow us to only require updating the uses of _mutable_ values of existential type (which are not `@objc`). This would likely include any Swift protocol delegates, since most of those will be `weak var`s, but it might carve out enough exceptions to make the source break more palatable.

Of course, I have a generally higher tolerance for source breaks, so if this problem is deemed big enough for the big, hard break in Swift 6, then I'm all for it. I'd rather end up in a world with fewer complex rules for type syntax, so a rule of "existential types are prefixed with `any`" is preferable to me in that regard. Just wanted to raise a couple of alternative paths forward in the event that the widest-reaching version of this proposal is unpalatable to some. 🙂

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 16, 2021, 2:55pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/17 "2021-11-16T14:55:33Z")

</div>

> [@Jumhyn](#):
>
> In the same vein, I'd be _strongly_ against allowing both `any P.Type` and `(any P).Type` and having those mean different things.

I agree with you that those things are extremely close to each other, yet they mean two totally different things. Metatatypes have two kinds merged into them today, this is rather awkward because not only does it limit our way into expressing a specific type constraint, but it's also the fact on why `type(of:)` remains compiler magic instead of having a pure swift function signature.

- `any P.Type` is the existential that accepts all meta types, which inherit from `P.Type` (e.g. `T.Type` from `T.self` where `T: P` which also means that `T.Type: P.Type`)

- `(any P).Type` is a static metatype (not an existential itself) of an existential for `P` (e.g. the result of `type(of: existentialP)` or `P.self`)

A small side note: The "true" `P.Type` is not expressible in Swift. Let this sink in for a bit. ;)

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [November 16, 2021, 3:10pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/18 "2021-11-16T15:10:36Z")

</div>

> [@DevAndArtist](#):
>
> e.g. the result of `type(of: existentialP)` or `P.self`

Hm—I'm not sure I understand this distinction fully. In Swift today, I thought that the result of `type(of: existentialP)` would be a `P.Type` (i.e., the metatype of some type conforming to `P`) while `P.self` is of type `P.Protocol`.

Even if I can bring myself to grasp this distinction fully, I don't think we should expose it to users as `(any P).Type` vs. `any P.Type`. We should come up with a better way of spelling those two (?) types (perhaps with the suggested `meta` keyword). Regardless, I don't think it's a problem that this proposal really needs to solve, as long as we're not boxing ourselves out of a potential future.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 16, 2021, 3:12pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/19 "2021-11-16T15:12:05Z")

</div>

One more thing, about 5 years ago we already tried to move this topic forward, but we (the original proposal authors) failed and withdrew our proposal. Later on @beccadax helped us to clear things a bit, but the proposal never seen any daylight. I still have it dusting in my outdated swift-evolution repository.

If anyone is interested in reading it and get a feeling on the issues around meta types, here's the link to it: [Refactor Metatypes](https://github.com/DevAndArtist/swift-evolution/blob/ed0f669976797a60a31b0bc2d71aaa44c07bb1d5/proposals/0126-refactor-metatypes.md)

The introduction of `any` keyword is probably our (second to) last chance to fix this in the language.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [November 16, 2021, 3:16pm UTC](https://forums.swift.org/t/pitch-introduce-existential-any/53520/20 "2021-11-16T15:16:11Z")

</div>

> [@DevAndArtist](#):
>
> The introduction of `any` keyword is probably our (second to) last chance to fix this in the language.

What exactly do you mean by this? Is this proposal consuming design space that would be required for a (separate) metatype-focused proposal, or is your concern that metatype issues won't on their own justify a source break and so would have to 'ride along' with the `any` proposal if the fixes require their own source breaks?

[Next page](https://forums.swift.org/t/pitch-introduce-existential-any/53520.md?page=2)
