> On Jan 12, 2017, at 2:58 PM, Jonathan Hull via swift-evolution
> <[email protected]> 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
> [email protected]
> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution