> On Jan 12, 2017, at 2:58 PM, Jonathan Hull via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> I really like swift’s error handling system overall. It strikes a good 
> balance between safety and usability.
> 
> There are some cases where it would be nice to throw errors, but errors are 
> rarely expected in most use cases, so the overhead of ‘try’, etc… would make 
> things unusable. Thus fatalError or optionals are used instead.  For example, 
> operators like ‘+’ could never throw because adding ’try’ everywhere would 
> make arithmetic unbearable. But in a few cases it would make my algorithm 
> much cleaner if I just assume it will work and then catch overflow/underflow 
> errors if they happen, and resolve each of them with special cases.  Or 
> perhaps I am dealing with user entered values, and want to stop the 
> calculation and display a user visible error (e.g. a symbol in a spreadsheet 
> cell) instead of crashing.
> 
> I would like to propose adding ‘throws?’ and ‘throws!’ variants to ‘throws’.
> 
> These would be used for cases where error handling is not the default desired 
> behavior, but having it as an option is desired occasionally.  Essentially, 
> the user would no longer have to preface the call with ‘try’, as the compiler 
> would implicitly add ‘try?’ or ‘try!’ respectively.
> 
> Thus, the function would act like a non-throwing function (either trapping or 
> returning an optional in the case of error), but the user could add ‘try’ to 
> the call to override that behavior and deal with the error more explicitly.
> 
> Another example would be bounds checking on arrays.  If subscripting arrays 
> was marked as ‘throws!’ then it would have the same default behavior it does 
> now (trapping on bounds error).  But a user could add ‘try?’ to return nil 
> for a bounds error in cases where they explicitly want that, or they could 
> add ‘try’ to deal with it as an error using do-catch.
> 
> I think this would really increase the availability of error handling in 
> areas where it is impractical right now…
> 
> Thanks,
> Jon
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

Another place I can see this being useful is for higher-order functions which 
"obviously" work on a throwing operation. The most obvious example would be a 
constructor for a Result type that collects the success or error result from a 
throwing closure:

enum Result<T> {
  case ok(T)
  case error(Error)

  init(_ f: () throws -> T) {
    do {
      self = .ok(try f())
    } catch {
      self = .error(error)
    }
  }
}

Having to write `Result { try somethingThatMightFail() }` feels a bit silly 
because "obviously" the operation you pass to Result is going to be able to 
fail. Such a feature does feel like it could be easy to misuse, though.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to