# \[Pitch\] Use “some” to express “some specialization of a generic type”

**URL:** <https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913>\
**Category:** Pitches\
**Created:** [June 8, 2022, 1:54pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913 "2022-06-08T13:54:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![oscbyspro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/oscbyspro/32/23689_2.png) [@oscbyspro](https://forums.swift.org/u/oscbyspro)\
**Post date:** [June 8, 2022, 1:54pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/1 "2022-06-08T13:54:02Z")

</div>

**Proposal**

The `some` keyword neatly replaces simple cases of `<T> where T: Protocol`. That said, I think there is an opportunity for a bit of syntactic sugar to elevate the readability of generics. In particular, I think it would be nice if `Generic<some A, some B>` could also be written as `some Generic` where A and B are the protocol requirements of Generic's type parameters.

**Reason**

The most obvious benefit of this is preventing generic type nesting beyond the point where every possible specialization is valid. Imagine that you are writing a String method that takes a range of positions and returns a Substring, where a position is generic over some encoding like UTF8, UTF16, or Character. Two equivalent function signatures, with and without syntactic sugar, may look like this:

```swift
func substring(_ range: Range<some Position>) -> Substring
func substring(_ range: Range<Position<some Encoding>>) -> Substring

```

Having written methods similar to this, it is apparent that the nesting is redundant because every specialization of `Position` is a `Position<some Encoding>`. I think, therefore, that allowing the former, a shorter and unambiguously equivalent signature, as shorthand for the latter would improve the readability of generics in cases such as the one described.

---

<div class="post-metadata">

**Author:** ![oscbyspro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/oscbyspro/32/23689_2.png) [@oscbyspro](https://forums.swift.org/u/oscbyspro)\
**Post date:** [June 13, 2022, 8:25pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/2 "2022-06-13T20:25:40Z")

</div>

I noticed that the compiler infers `T: Encoding` from `Position` for `<T>` syntax:

```swift
func substring<T>(_ range: Range<Position<T>>) -> Substring // OK
func substring<T>(_ range: Range<Position<T>>) -> Substring where T: Encoding // OK

```

I think this illustrates an expectation that similar inference should be available with `some`.

---

<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:** [June 13, 2022, 9:40pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/3 "2022-06-13T21:40:25Z")

</div>

I am definitely intrigued by this idea! I haven’t thought through all the implications, but broadly it makes sense to me not to have to manually, syntactically ‘forward’ all the generic arguments to parameters you’re accepting.

A couple questions that immediately come to mind are:

- Would we support `some S` in return position? Currently there’s no equivalent ‘long hand’ syntax, but we also don’t have that for `some P` in return position so maybe that’s fine.
- Would we support unbound generic types as generic constraints themselves? Currently `some P` in argument position is always equivalent to `<T> where T: P`, and it might be nice to keep the symmetry (i.e., by letting users write `<S> where S: Set` instead of generalizing over the element type specifically.

---

<div class="post-metadata">

**Author:** ![ensan-hcl](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ensan-hcl/32/15186_2.png) [@ensan-hcl](https://forums.swift.org/u/ensan-hcl)\
**Post date:** [June 14, 2022, 12:03am UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/4 "2022-06-14T00:03:38Z")

</div>

> [@Jumhyn](#):
>
> - Would we support `some S` in return position? Currently there’s no equivalent ‘long hand’ syntax, but we also don’t have that for `some P` in return position so maybe that’s fine.

I think supporting opaque result types is fine, and I found that this idea is actually extending the range of types which can be expressed in Swift;

```swift
struct Foo<Wrapped: Collection<Int>> where Wrapped.Index == Int {
    var wrapped: Wrapped
}
var foo: Foo<some Collection<Int where Index == Int>> // there is no corresponding expression for `some`
var foo: some Foo // with the idea

```

---

<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:** [June 14, 2022, 4:13am UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/5 "2022-06-14T04:13:04Z")

</div>

This is definitely needed. The asymmetry we have at the moment doesn't make any sense.

```swift
// Compiles.
func ƒ(_: some BidirectionalCollection & RandomAccessCollection & ExpressibleByArrayLiteral) { }

// Reference to generic type 'Array' requires arguments in <...>
func ƒ(_: some Array) { } 

```

That said, I can't tell if your examples should actually compile—is `some Position` really meaningful enough?. It would be nice to have examples that either don't rely on code we don't have, or if you could provide the code.

---

<div class="post-metadata">

**Author:** ![oscbyspro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/oscbyspro/32/23689_2.png) [@oscbyspro](https://forums.swift.org/u/oscbyspro)\
**Post date:** [June 14, 2022, 7:31am UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/7 "2022-06-14T07:31:55Z")

</div>

I see prefixing a generic type with `some` as a readable way of propagating inference of type parameter conformances. I realize this depends on a `some _` placeholder capable of doing this for a single type parameter, which perhaps should have been the core of this pitch. Given a type `struct Foo<A, B> where A: P, B: Q`, `some Foo` would mean `some Foo<_, _>` which would mean `Foo<some _, some _>` which would mean `Foo<some P, some Q>`.

---

<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:** [June 14, 2022, 11:36am UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/8 "2022-06-14T11:36:34Z")

</div>

> [@oscbyspro](#):
>
> Foo\<A, B\>

To be clear, some Foo\<Int\> would be rejected, right?

---

<div class="post-metadata">

**Author:** ![oscbyspro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/oscbyspro/32/23689_2.png) [@oscbyspro](https://forums.swift.org/u/oscbyspro)\
**Post date:** [June 14, 2022, 1:27pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/9 "2022-06-14T13:27:11Z")

</div>

Yes, I think you would have to specify both type parameters. Maybe when generic opaque type constraints are available, it would make sense to use the same syntax in this case as well and write something like: `some Foo<.B == Int>`, which would be the same as `some Foo<_, Int>` or `Foo<some _, Int>` with the pitched syntax and `Foo<some P, Int>` with the current syntax. I think `some Foo<Int>` only makes sense if there exists an analog to primary associated types.

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [June 14, 2022, 1:53pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/10 "2022-06-14T13:53:03Z")

</div>

This has occurred to me as well, but I suppose it only makes sense for input parameters, e.g. `some Array` could not be a return type. The function implementer would know what `Element` is but as a caller you wouldn't. Unless the idea is that the actual type is revealed to you implicitly:

```nohighlight
func foo() -> some Array { 
   [1, 2, 3]
}

let x = foo() // x is now [Int]

```

EDIT:

Turns out this already works for `some Collection`, so I guess it would make sense for `some Array` as well.

```swift
  func foo() -> some Collection {
    [1, 2, 3]
  }

  func bar() {
    let baz = foo() // some Collection in XCode
    print(type(of: baz)) // prints Array<Int>
  }

```

---

<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:** [June 14, 2022, 2:38pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/11 "2022-06-14T14:38:08Z")

</div>

> [@GreatApe](#):
>
> ```swift
> `some Array` could not be a return type. 
> 
> ```

For now. I haven't seen people clamoring for it but that doesn't mean it's not useful for anything.

E.g. I never found a use for `some Sequence`, even though I was just able to get rid of a bunch of usage of `AnySequence` in favor of `some Sequence<ConcreteType>`. And `some Sequence` still compiles. So why shouldn't every generic type as well?

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [August 4, 2022, 1:07pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/12 "2022-08-04T13:07:45Z")

</div>

I like the idea a lot! Would love to hear any doubts or counter arguments, but my initial reaction is +1

---

<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:** [March 8, 2023, 9:24am UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/13 "2023-03-08T09:24:10Z")

</div>

I'm starting to recognize that people want the `any` variant of this, as well as the `some` one.

> [@Why can't I cast \`Woo\<Any\>\` to \`Woo\<Int\>\` concrete type? But \`Array\<Any\>\` to \`Array\<Int\>\` is OK?](https://forums.swift.org/t/why-cant-i-cast-woo-any-to-woo-int-concrete-type-but-array-any-to-array-int-is-ok/63556):
>
> In Swift, we can cast a type of Array\<Any\> to Array\<Int\> if the underlying type is in fact a Array\<Int\>: let anyArray = [1,2,3] as Array\<Any\> let arrayActual = anyArray as! Array\<Int\> // Ok But if I try the same thing with my own generic types, I get a warning from the compiler: Cast from 'Woo\<Any\>' to unrelated type 'Woo\<Int\>' always fails and a runtime crash: struct Woo\<Boo\> { let boo: Boo } let anyWoo = Woo(boo: 3) as Woo\<Any\> let wooActual = anyWoo as! Woo\<Int\> // Crash What am I m…

> [@Erasing (or mapping) value type parameters](https://forums.swift.org/t/erasing-or-mapping-value-type-parameters/63553):
>
> i have a struct, let’s call it DriverOptions\<T\> that has a type parameter, and lots and lots of stored properties: @frozen public struct DriverOptions\<Authentication\> where Authentication:AuthenticationMode { public var authentication:Authentication? public var connectionTimeout:Milliseconds public var replicaSet:String? public var tls:Bool? ... the type parameter is needed when building the DriverOptions instance itself, but now i want to store it insi…

> [@Typealias conformance to protocols, why can't this simple thing be implemented?](https://forums.swift.org/t/typealias-conformance-to-protocols-why-cant-this-simple-thing-be-implemented/63302/49):
>
> It's something like that, but not that. If you don't specify, the class constraint is assumed. (UIView in this case.) class MyViewDelegate: MyDelegate\<UIView\> { override func getView() -\> UIView { .init() } } class MyTableViewDelegate: MyDelegate\<UITableView\> { override func getView() -\> UITableView { .init() } } getViewIfPossible(delegate: MyViewDelegate()) // UIView?.some getViewIfPossible(delegate: MyTableViewDelegate()) // UIView?.none So, just switch to a protocol: protocol Delega…

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 8, 2023, 5:25pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/14 "2023-03-08T17:25:19Z")

</div>

What if you could write:

```swift
func substring(_ range: Range<some>) -> Substring

```

and the constraints on the generic parameters would be inferred from `Range`'s requirements? That avoids the need to restate the bounds, while also keeping the number and position of implied generic parameters easy to read for someone looking at the declaration. We infer bounds on `T` when you write `func foo<T>(_: Range<T>)`, so this seems like a nice consistent shorthand.

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [March 8, 2023, 5:46pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/15 "2023-03-08T17:46:11Z")

</div>

> [@Joe\_Groff](#):
>
> What if you could write:
> 
> ```swift
> func substring(_ range: Range<some>) -> Substring
> 
> ```
> 
> and the constraints on the generic parameters would be inferred from `Range`'s requirements?

This already works via the usual requirement inference mechanism:

```swift
func substring(_ range: Range<some Any>)

```

So if you parsed `some` as `some Any` it might just work.

---

<div class="post-metadata">

**Author:** ![Alejandro](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro/32/46197_2.png) [@Alejandro](https://forums.swift.org/u/Alejandro)\
**Post date:** [March 8, 2023, 5:50pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/16 "2023-03-08T17:50:26Z")

</div>

The interesting thing I would like is the `any` variant:

```swift
struct Generic<T> {
  let value: T
}

func something() -> any Generic {
  if Bool.random() {
    return Generic(value: 123)
  } else {
    return Generic(value: "hello world")
}

```

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [March 8, 2023, 5:51pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/17 "2023-03-08T17:51:13Z")

</div>

> [@anon9791410](#):
>
> I'm starting to recognize that people want the `any` variant of this, as well as the `some` one.

An existential type `any P & Q` is really something like this, we’re that syntax to exist: `any <T where T: P, T: Q> T`; that is, it’s a container for a value of type `T` which is a generic parameter in a local generic signature with some requirements imposed on it. Similarly `any Sequence<Int>` becomes `any <T where T: Sequence, T.Element == Int> T`.

Your `any Array` would become `any <T> Array<T>` in the more general syntax; so it’s a container storing an `Array<T>` (not just T) and the T is type erased. You could also have more than one erased parameter, for eg `any Dictionary`.

Not sure we’ll ever get “fully generalized existentials” in the surface language, but this is fact how they’re modeled internally in the compiler.

(If I ever get around to finishing it, Part II of [Compiling Swift generics](https://forums.swift.org/t/compiling-swift-generics-part-i/60898) has a chapter on existential types).

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [March 8, 2023, 5:53pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/18 "2023-03-08T17:53:02Z")

</div>

please can we surface this? this would be immensely helpful.

---

<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:** [March 8, 2023, 8:14pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/19 "2023-03-08T20:14:11Z")

</div>

> [@Joe\_Groff](#):
>
> That avoids the need to restate the bounds, while also keeping the number and position of implied generic parameters easy to read for someone looking at the declaration.

We need this kind of control sometimes…

```swift
func ƒ(_: [String: some Any]) { }
func ƒ(_: [some Any: String]) { }

```

…but otherwise, I don't think it's so good when there's more than one placeholder type.

```swift
func ƒ(_: [some Any: some Any]) { } // compiles
func ƒ(_: some Dictionary) { } // doesn't; would be better

```

Being able to put `some` in either place for types with a single generic placeholder, as per your whim, seems consistent with `case`-binding:

```swift
switch "🇸🇴" as Optional {
case .some(let _): break
case let .some: break
default: break
}

```

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [March 8, 2023, 8:31pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/20 "2023-03-08T20:31:37Z")

</div>

> [@anon9791410](#):
>
> …but otherwise, I don't think it's so good when there's more than one placeholder type.
> 
> ```swift
> func ƒ(_: [some Any: some Any]) { } // compiles
> func ƒ(_: some Dictionary) { } // doesn't; would be better
> 
> ```

I think that's where I disagree it's better. Although `Dictionary` is a common type that people are familiar with, seeing `some Foo` for an unknown type or protocol would become a lot more ambiguous, since it could be either introducing one generic parameter bound to a protocol named `Foo`, or any number of generic parameters corresponding to the parameters of a generic type `Foo`.

A reasonable midpoint might be to allow for variadic implicit generic parameters, so you could write

```swift
func f(_: Dictionary<some...>)

```

or whatever syntax we decide for variadic type variables as a way to keep it clear that multiple type parameters are being introduced.

---

<div class="post-metadata">

**Author:** ![bbrk24](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bbrk24/32/27370_2.png) [@bbrk24](https://forums.swift.org/u/bbrk24)\
**Post date:** [March 8, 2023, 8:35pm UTC](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913/21 "2023-03-08T20:35:28Z")

</div>

This probably deserves its own thread, but occasionally I find myself reaching for TypeScript's `infer` operator. Like `let`, `infer` creates a new binding, but that binding is to a type. Here's an example I just encountered:

```swift
    // Inside a generic struct
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: Key.self)
        if Value.self == Optional<infer Wrapped>.self {
            value = try container.decodeIfPresent(Wrapped.self, forKey: key)
        } else {
            value = try container.decode(Value.self, forKey: key)
        }
    }

```

The design of Codable aside (as there might be a better way to do this), I do occasionally wish something like this were possible.

[Next page](https://forums.swift.org/t/pitch-use-some-to-express-some-specialization-of-a-generic-type/57913.md?page=2)
