Combining ? with throwing when there's no reasonable default

Does it matter if τ = Never is the only possible subtype? It's an uninhabited type, after all. I'd expect that to help, if not with generics.

I agree. Several other things were different back in Swift 1 days while we were discussing this - e.g. we didn't have Never at the time. I'm +1 on moving throw to being an expression.

6 Likes

Having to simplify τ < X to τ = X OR τ = Never instead of simply τ = X makes type-checking much harder, yes.

There are several old threads on this topic. This is the most recent. I haven't seen anyone mention a Result-based solution. I don't like it as much as an operator, but considering I want this initializer anyway, calling get() is nothing else to add.

public extension Result {
  /// `success` for `Optional.some`s; `failure` for `.none`s.
  init(
    success: Success?,
    failure getFailure: @autoclosure () -> Failure
  ) {
    self =
      success.map(Self.success)
      ?? .failure( getFailure() )
  }
}
let a = try Result( success: maybeA(), failure: SomeError() ).get()

I feel bridging the worlds of nil failing and throwing initializers with as little friction as possible is important. There is a tendency I have noticed in myself to nil coalesce to a bogus value that I'll fix real soon(TM). But if I have the right tool to reach for, I am more likely to do the right thing.

I proposed a slightly different (non-operator) spelling: