# Opaque result types

**URL:** <https://forums.swift.org/t/opaque-result-types/15645>\
**Category:** Pitches\
**Created:** [August 29, 2018, 9:49pm UTC](https://forums.swift.org/t/opaque-result-types/15645 "2018-08-29T21:49:17Z")\
**Posts on this page:** 20\
**Page:** 14

<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:** [February 27, 2019, 11:31pm UTC](https://forums.swift.org/t/opaque-result-types/15645/265 "2019-02-27T23:31:57Z")

</div>

Thinking a bit further on this, the syntax could be extended to allow for referencing the opaque type from other contexts (allowing constructions indicating “these two functions return the same opaque type”) by doing something like:

```
makeIntCollection() -> makeMeACollection<Int>(_:).Q { // or makeMeACollection<Int>(_:).Result if result type is anonymous?
    return makeMeACollection(Int.self)
}

```

I’m also perfectly fine with the result type being unable to be referenced if it isn’t named explicitly.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 27, 2019, 11:35pm UTC](https://forums.swift.org/t/opaque-result-types/15645/266 "2019-02-27T23:35:20Z")

</div>

> [@Jumhyn](#):
>
> the syntax could be extended to allow for referencing the opaque type from other contexts (allowing constructions indicating “these two functions return the same opaque type”)

Previously we’ve talked about enabling that using opaque type aliases. As we discuss syntax it’s worth keep that possible enhancement in mind. Does `some` work as well there as it does in the return type of a function signature? I’m not sure...

---

<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:** [February 27, 2019, 11:44pm UTC](https://forums.swift.org/t/opaque-result-types/15645/267 "2019-02-27T23:44:23Z")

</div>

I did read some of that discussion. My thinking with this syntax is that it avoids the litany of `typealias`es that have names like `ResultTypeOfSomeMethod`. Since the opaque type is tied to the method itself, why not scope the name of that type around the method itself as well? The `typealias` approach could be an alternative as well if the user doesn’t want to have one method appear somehow “subordinate” to another since it inherits the result type.

I think the usage of `some` there works fine, in any case:

```
typealias some CollectionType<T>: MutableCollection & RangeReplaceableCollection = [T]

```

The above reads clearly to me.

---

<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:** [February 28, 2019, 1:20am UTC](https://forums.swift.org/t/opaque-result-types/15645/268 "2019-02-28T01:20:42Z")

</div>

I think `some` reads pretty well for me. I can throw out the idea of `unclear`.

```swift
protocol Shape { ... }
func doSomeMagic() -> unclear Shape { ... }

```

(Some others ones that came to mind were `obscure` and `vague` return types).

---

<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:** [February 28, 2019, 4:28am UTC](https://forums.swift.org/t/opaque-result-types/15645/269 "2019-02-28T04:28:50Z")

</div>

> [@John\_McCall](#):
>
> One concern I have with `some` — and perhaps I'm off-base to worry about this — is that it relies on a fairly nuanced sense of the English word that might be unfamiliar or confusing to non-native speakers. It's "some" specifically in the sense of "a non-specific example of", like "some kid ran into me in the park", not "some" as an alternative to "none" or "lots". So not only would we be using "some" in two different fairly core places in the language, but we'd actually be using a different sense of it in each place.

I share these concerns. It is true that "some" complements "any," but neither of these words are ultimately very descriptive of the concepts to which they pertain:

Not only is "some" reused as an `Optional` case, even in an alternative universe where that isn't the case, there is nothing a priori that tells a reader that a "some" type (not a "sum type"!) is an opaque type. This is also my criticism of "any" types, which do nothing to tell the user that they are used for type erasure based on the name alone. At least, however, the erasure is made manifest by the lack of generic parameters.

Now, suppose a reader encounters the keyword "some" and tries to look it up. How will they know which chapter to turn to in _The Swift Programming Language_? What can they expect to find if they google "Swift some"?

I do not see any reason to try to be clever in the choice of keyword. If this particular feature will be described as an "opaque type," then it is appropriate to use the keyword `opaque` or `opaquetype`, just as we use the keyword `typealias` for type aliases, `associatedtype` for associated types, and `class` for classes--without worrying that a user would be confused that `class Room` models a classroom.

---

<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:** [February 28, 2019, 4:45am UTC](https://forums.swift.org/t/opaque-result-types/15645/270 "2019-02-28T04:45:07Z")

</div>

I mused about words like `abstract` and `interface`, which are obviously problematic but not entirely unjustifiable.

As others alluded to, "some" has a usability problem in communication. Imagine two programmers talking about their code and a "some" type comes up, one would have to either work really hard to make the context clear or remember to use "opaque" to describe it, and hope the other party to make the connection...not being able to search on the internet would be a symptom of the same problem (although I think search algorithms can be trained to overcome it) .

I put my vote in for `arbitrary`.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [February 28, 2019, 5:49am UTC](https://forums.swift.org/t/opaque-result-types/15645/271 "2019-02-28T05:49:45Z")

</div>

What about some variation of ‘Any’? I think it reads very clearly. As far as the declaration goes, I don’t think the user of the function needs to care if the abstract, opaque result is always the same type or not; that’s information that the compiler cares about. You just get an `Any<Shape>` and treat it like a kind of less-restricted existential.

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [February 28, 2019, 6:06am UTC](https://forums.swift.org/t/opaque-result-types/15645/272 "2019-02-28T06:06:32Z")

</div>

I think we want to reserve spellings like that for the possible use of generalized existentials.

---

<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:** [February 28, 2019, 6:17am UTC](https://forums.swift.org/t/opaque-result-types/15645/273 "2019-02-28T06:17:34Z")

</div>

As far as my understanding of this core feature goes, the opaque type is some concrete type that is erased and fixed to the given constraints and type of the return type. In that sense, can we maybe call it `erased` which is a concept most Swift developer already are familiar with, it has no ambiguity like `some` or `opaque`!?

```swift
protocol Shape { ... }
func translucentRectangle() -> erased Shape { ... }

```

---

<div class="post-metadata">

**Author:** ![Vogel](https://avatars.discourse-cdn.com/v4/letter/v/e95f7d/32.png) [@Vogel](https://forums.swift.org/u/Vogel)\
**Post date:** [February 28, 2019, 6:23am UTC](https://forums.swift.org/t/opaque-result-types/15645/274 "2019-02-28T06:23:43Z")

</div>

It surprises me that this thread is still around.

It seems like some people here think of this as a cute little convenience feature, but the impact it has on how types work is quite large and ultimately, hurts composability a lot.

It isn't even powerful in terms of decluttering code since the wrapper types still have to be written, and it would be particularly horrible if the standard library would make use of it instead of the existing wrapper-types for reversed collections etc – because of the already mentioned composability issues.

Here is one of the main problems that is inherent to the proposed concept:

```
protocol A {
    associatedtype B
}

struct C { }

func d() -> opaque A where B: C {
    return ...
}

//just some kind of convenience method that always ends up calling d:
func e() -> opaque A where B: C {
    //other stuff...

    return d()
}

let f = [d(), e()] //OH NO, ERROR, NOT THE SAME TYPES (even though they actually are, but we can't express that.)

```

---

<div class="post-metadata">

**Author:** ![zwaldowski](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/zwaldowski/32/21801_2.png) [@zwaldowski](https://forums.swift.org/u/zwaldowski)\
**Post date:** [February 28, 2019, 6:24am UTC](https://forums.swift.org/t/opaque-result-types/15645/275 "2019-02-28T06:24:50Z")

</div>

I like `some` as much as anyone, but what it really got me thinking about is perspective. (This is going somewhere, I promise.)

`some` reads as a promise on the part of the author of the method: “I’m giving you _some_thing of this type”. The client doesn’t know concretely what; the author (and the compiler) do.

Consider the consumer’s side of that promise. In terms of what methods you can call on the returned type, how you can `let` it out, or basically what the compiler prevents you from doing with the opaque type, it’s more akin to “this method wants to give me _any_thing of this type, I have to handle whichever one it actually is the same.”

But those two phrasings aren’t mutually exclusive, you know? They’re two sides of the same coin. (“Can I interest you in any beverages?” “Some wine, please”) I then recalled that this fancy glass rectangle I’m typing this on is also a thesaurus; indeed, “some” and “any” show up high in one another’s related words.

Which brings me to: If opaque return types and the syntax for existentials are such distinct design spaces that we’re hunting for a keyword for the former, why would we choose one that’s arguably interchangeable with ones already used for the latter? Won’t that be tremendously confusing to someone seeing both features for the first time?

Or, the inverse: if we are to come to consensus on `some` (yay! consensus!), doesn’t its closeness to “any” imply a superset/subset overlap than is (perhaps) more than we are intending intend for the “I don’t want to give you a concrete type for this right now” space?

Maybe it’s a crackpot theory, or maybe we should’ve stuck with `opaque` we were ahead. 😉 Either way, can’t wait to see a proposal moving forward.

---

<div class="post-metadata">

**Author:** ![PoltoraIvana](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/poltoraivana/32/7450_2.png) [@PoltoraIvana](https://forums.swift.org/u/PoltoraIvana)\
**Post date:** [February 28, 2019, 6:41am UTC](https://forums.swift.org/t/opaque-result-types/15645/276 "2019-02-28T06:41:37Z")

</div>

> [@Vogel](#):
>
> Here is one of the main problems that is inherent to the proposed concept:
> 
> ```swift
> 
> ```

I am not sure that we are allowed to call e() as return in d(), since the pitch states that the concrete type is needed as a return type in opaque functions.  
Anyway, as I understand it, it's the selling point of opaque types: homogeneity vs heterogeneity of generalized existentials.

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [February 28, 2019, 9:54am UTC](https://forums.swift.org/t/opaque-result-types/15645/277 "2019-02-28T09:54:38Z")

</div>

Any thoughts on more symbolic syntax? How about single-quoted `'T'` instead of `opaque T`. This feature is meant to be used pretty commonly, right?, so terser syntax with semantic meaning might be preferable to a keyword. These could still be described as opaque types without the awkward clashes with English like the `opaque Shape` example mentioned above.

(I'm not wholly sold on this idea, but seems worth raising whilst we are spitballing terms...)

---

<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:** [February 28, 2019, 2:20pm UTC](https://forums.swift.org/t/opaque-result-types/15645/278 "2019-02-28T14:20:26Z")

</div>

> [@xwu](#):
>
> If this particular feature will be described as an "opaque type," then it is appropriate to use the keyword `opaque` or `opaquetype` , just as we use the keyword `typealias` for type aliases, `associatedtype` for associated types, and `class` for classes

After sleeping on this I agree. Using `some` would hurt searchability and describes the feature no better than `opaque` does. If we go with `opaquetype` then IMO the type should have to be given a name explicitly, so `-> opaquetype Collection where _.Element == Int` would be disallowed.

> [@Vogel](#):
>
> ```
> let f = [d(), e()] //OH NO, ERROR, NOT THE SAME TYPES (even though they actually are, but we can't express that.)
> 
> ```

There have been proposed syntaxes that would allow this sort of behavior, either via a `typealias` or some other annotation of the return type, so that something like this would be legal:

```
typealias opaque Q: A where B: C = MyConcreteType

func d() -> Q {
    return ...
}

func e() -> Q {
    return d()
}

func f() -> e().ResultType {
    e()
}

let f = [d(), e(), f()] // OK!

```

Does this address your concerns?

> [@bzamayo](#):
>
> How about single-quoted `'T'` instead of `opaque T`.

For the same reason I've soured somewhat on `some`, I think this would be even worse. Single quotes don't suggest any meaning at all, and don't even really mirror any other syntax related to this feature. With `Array` and `Dictionary` shorthand, you can at least argue that the terse syntax mirrors the construction of a literal, and with `Optional` the shorthand mirrors `Optional` chaining. Furthermore, with the forward motion on [character integer literals](https://forums.swift.org/t/prepitch-character-integer-literals/10442), we would be introducing two entirely unrelated uses of single quotes.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [February 28, 2019, 2:37pm UTC](https://forums.swift.org/t/opaque-result-types/15645/279 "2019-02-28T14:37:56Z")

</div>

> [@Jumhyn](#):
>
> ```swift
> typealias opaque Q: A where B: C = MyConcreteType
> 
> ```

I think it would read best like this:

```swift
opaque typealias Q: (A where B: C) = MyConcreteType

```

In fact, I might go so far as to discourage the use of anonymous opaque types in function signatures. It seems far more desirable to have the typealias written out separately.

---

<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:** [February 28, 2019, 2:45pm UTC](https://forums.swift.org/t/opaque-result-types/15645/280 "2019-02-28T14:45:55Z")

</div>

> [@Nevin](#):
>
> ```
> opaque typealias Q: (A where B: C) = MyConcreteType
> 
> ```

I like the parentheses but am iffy on having them be required, that seems more appropriate to offer as a choice if teams want to adopt it.

> [@Nevin](#):
>
> In fact, I might go so far as to discourage the use of anonymous opaque types in function signatures.

I would be in support of disallowing it outright as long as the following is acceptable:

```
func f() -> opaque Q: Collection where Q.Element == Int {
    [Int]()
}

```

I think being able to specify the opaque type inline is important for avoiding a bunch of `typealias opaque FReturnType: ... = [Int]` style declarations. I believe that the solution for that is allow for a way to reference directly "the return type of function `f()`," which could be useful in contexts other than opaque types anyway.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [February 28, 2019, 2:50pm UTC](https://forums.swift.org/t/opaque-result-types/15645/281 "2019-02-28T14:50:19Z")

</div>

I agree that `opaque typealias` reads much better than `typealias opaque`. I don’t think `some typealias` makes sense at all and `typealias some` doesn’t really work because the “some” applies to the constraints, not the name of the typealias. With that in mind, `opaque` might be the best choice after all.

`opaquetype` has also been mentioned, but that would be awkward when used with `typealias`: `opaquetype typealias` is not only redundant, but immediately repetitive.

---

<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:** [February 28, 2019, 3:10pm UTC](https://forums.swift.org/t/opaque-result-types/15645/282 "2019-02-28T15:10:22Z")

</div>

I guess I group things differently in my head. I don’t think of `typealias opaque...` as a construction at all, really. Rather, `opaque Q: Collection where Q.Element == Int` reads as “an unknown concrete type conforming to `Collection` with `Int` as its `Element`. Thus, `typealias opaque` just says `typealias <unknown type> = <concrete type>` which seems very similar to how `typealias` is used already. Breaking up `opaque` from the type definition might read more grammatically, but it doesn’t really describe what’s going on. The _type_ is opaque, not the `typealias`. Also, unless we disallow the “inline” definition of `opaque` types in the function declaration, having `opaque` attached to the type in one context but attached to `typealias` in another is inconsistent just for the sake of making the `typealias` more sentence-y.

---

<div class="post-metadata">

**Author:** ![jechris](https://avatars.discourse-cdn.com/v4/letter/j/a5b964/32.png) [@jechris](https://forums.swift.org/u/jechris)\
**Post date:** [February 28, 2019, 3:36pm UTC](https://forums.swift.org/t/opaque-result-types/15645/283 "2019-02-28T15:36:31Z")

</div>

I guess there is something I did not understand, but I would expect opaque typealias to be more something like:

```swift
typealias Q = opaque A where B: C

func d() -> Q {
    return ...
}

func e() -> Q {
    return d()
}

```

With no reference to any concrete type as it does not appear inside function signature (when not using typealias).

As for `opaque` naming, what about `anonymized`?

```swift
func makeMeACollection<T>(_: T.Type) -> anonymized Q: MutableCollection & RangeReplaceableCollection where Q.Element == T {
    return [T]()
}

```

---

<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:** [February 28, 2019, 3:47pm UTC](https://forums.swift.org/t/opaque-result-types/15645/284 "2019-02-28T15:47:34Z")

</div>

> [@jechris](#):
>
> With no reference to any concrete type as it does not appear inside function signature (when not using typealias).

My understanding is that the goal of the `typealias` would be to fix the concrete type so that when the alias is used in different methods, you can guarantee that they both return the same type. As written above, you would have non-equivalence between

```
typealias Q = A where B: C

```

and

```
typealias P = A where B: C

```

Which seems wrong given the implications of an alias. The other option would be that `d()` and `e()` do not have compatible return types, as if you had defined `opaque` inline.

[Previous page](https://forums.swift.org/t/opaque-result-types/15645.md?page=13)

[Next page](https://forums.swift.org/t/opaque-result-types/15645.md?page=15)
