[swift-evolution] Proposal: Typed throws

Chris Lattner clattner at apple.com
Sat Dec 5 10:49:05 CST 2015


On Dec 4, 2015, at 12:54 PM, David Owens II <david at owensd.io> wrote:
>>> 
>>>  do {
>>>      try buyFavoriteSnack("Alice", vendingMachine: vendingMachine)
>>>  } catch VendingMachineError.InvalidSelection {
>>>      print("Invalid Selection.")
>>>  } catch VendingMachineError.OutOfStock {
>>>      print("Out of Stock.")
>>>  } catch VendingMachineError.InsufficientFunds(let coinsNeeded) {
>>>      print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
>>>  } catch { fatalError("this is always needed…”) }
>> 
>> But this is printing.  Of course you should be able to generically display an error, but you don’t need static typing for that.  Also, I certainly hope you are not actually repeating all this stuff at every catch site.
> 
> This was a sample from the Swift docs: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42-ID508. I added the missing final `catch` that is required with Swift today.
> 
> The point being, the error enum is fully defined but we still need the final `catch` at the end because there is no type information on the `throws` annotation for `buyFavoriteSnack`. So unlike the case when dealing with enums and switch-statements, we lose all compile-time information about coverage of error states when we could know them. The current implementation of `throws` is the only (as far as I can tell) place in Swift that turns a compile-time validation problem into a run-time validation problem.
> 
> That’s my concern.
> 
> Instead, if we could annotate throws, we could move this into a compile-time validation.

FWIW, if you’re interested in the Swift error handling model, then this document is required reading:
https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst

John drove the design efforts for error handling in Swift 2 and wrote it to capture the thinking of the team.  There is also this document that describes the intent of the feature as well, but it has been subsumed by The Swift Programming Langauge:
https://github.com/apple/swift/blob/master/docs/ErrorHandling.rst


My take on it is that typed throws would be a great feature to add for all of the reasons you specify.  However, rolling it out in Swift 2 would have been very problematic, because we didn’t (and still don’t) have the Swift 3 resilience model in place.

The resilience model addresses how the public API from a module can evolve without breaking clients (either at the source level or ABI level).  Notably, we want the ability to be able to add enum cases to something by default, but also to allow API authors to opt into more performance/strictness by saying that a public enum is “fragile” or “closed for evolution”.

In the case of typed throws, you should only get the “exhaustiveness checking” of catch blocks if you’re catching an enum defined in your own module, or if it is a public enum from some other module that is defined as being fragile.

-Chris



More information about the swift-evolution mailing list