SE-0244: Opaque Result Types

After mulling this over in the back of my head this week, here’s a late-breaking addendum to my earlier review.

I expressed concerns about confusion and cognitive load. I notice this was a common theme in the responses: people find this feature hard to reason about.

Much of the discussion focused on the word some, but perhaps the real problem is anonymity. This proposal creates many mutually incompatible anonymous types that have the same spelling (some Foo) in code.

The problem is perhaps most obvious in this poetically bollixing error message:

cannot assign value of type '(__opaque opaque.(file).g()@/tmp/opaque.swift:8:6)' to type '(__opaque opaque.(file).f()@/tmp/opaque.swift:4:6)'

I’m sure a release version of the compiler could generate a better error message, but the difficulty of expressing that error well may signal the deeper underlying problem that their anonymity makes these types communication-proof: hard to talk about, hard to think about.


An alternative to consider: make the opaque type aliases described under Future Directions the only way to declare opaque types. This gives each distinct opaque type a distinct name, which has several advantages:

  • It makes it easier for API consumers to reason about when and why opaque types are distinct.
  • It makes compiler errors much easier to understand.
  • It helps API authors reason about how many distinct types they are exposing.
  • The current proposal (1) gives no way to express that different functions return the same opaque type, and (2) AFAICT gives no way to pass an opaque type returned from a library to other functions, or even store it in a variable with a type annotation, without using an existential. This rules out many rudimentary refactoring and abstraction techniques, and will be an immediate source of pain. Named types could help address both these problems.
  • This could conceivably address some of the use cases for which people have wanted newtype.

There are disadvantages too:

  • It’s more verbose.
  • It leads to a proliferation of names.
  • It may not serve the future scenario Joe envisions of passing some P as a parameter.

To be clear, I’d still vote +1 for the proposal as is, in deference to others who understand the problem better than I do. I mention this as something to consider if the current proposal just isn’t sitting quite right.

15 Likes