[swift-evolution] Proposal: Typed throws

John McCall rjmccall at apple.com
Fri Dec 4 18:07:31 CST 2015


> On Dec 4, 2015, at 12:54 PM, David Owens II <david at owensd.io> wrote:
>> On Dec 4, 2015, at 11:54 AM, John McCall <rjmccall at apple.com> wrote:
>> 
>>> On Dec 4, 2015, at 11:36 AM, David Owens II <david at owensd.io> wrote:
>>> For the most part, I feel that typed errors are more of a response to how we need to handle errors within Swift today.
>>> 
>>>  var vendingMachine = VendingMachine()
>>>  vendingMachine.coinsDeposited = 8
>>> 
>>>  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.

Ah, right, I knew I recognized that example.

This code is intended to demonstrate the ability to chain catches more than it is intended to demonstrate best practice for working with errors.  In real code, this would be better done by giving VendingMachineError a conformance to CustomStringConvertible and just having this at the catch site:

  catch {
    print(error)
  }

> 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.

AnyObject and ImplicitlyUnwrappedOptional come immediately to mind.  I expect that we will gradually more dynamic features, hopefully more like the former than the latter.

> That’s my concern.
> 
> Instead, if we could annotate throws, we could move this into a compile-time validation.

I understand what you want to do.  I am saying that, as a language designer, I am reluctant to add features that seem to be, frankly, aspirational bluffs.

I would like you to think about what your concrete error types will look like in their entirety and reconsider whether that static type would actually tell you anything useful.  I certainly don’t believe that they’re worth the costs, which are quite high.

> Yes, I do realize that multiple error types would complicate that, but honestly, I’d rather than the limitation that only a single error type can be propagated up the callstack than to have the ability to have no typed error information at all.

This is what I mean.  Your code will use other code, which will produce its own errors.  Your "single error type” will therefore end up providing at least one case, and probably several, that simply wraps other, opaque error types without providing any extra information.  Thus, it will simply rebroadcast all of your library dependencies, and it will need to be modified whenever your implementation changes.  You will have meaningless translation/wrapping code scattered at every library boundary just to appease the compiler, and anybody trying to recognize specific problems will have to pattern match through an arbitrarily-nested tree of such wrappers.  This is all essentially an inevitable consequence of statically typed errors, and it is a bad outcome.

John.


More information about the swift-evolution mailing list