[swift-evolution] [Pitch] Throwing unwrap operators
Robert Bennett
rltbennett at icloud.com
Sun Jul 30 13:24:59 CDT 2017
This idea was sparked by conversation in another thread about a more concise way to write the following:
guard let x1 = f1(), let x2 = f2(), ... else { ... }
doSomething(with: x1)
doSomething(with: x2)
...
It was suggested to write a function that throws when an optional is nil, and then wrapping the calls to f1, f2, ... in that function, and then wrapping *those* in a do-catch block. This would both exit early in case one value was nil, and also use the values as soon as they’re available instead of needing to assign them to a temp variable first and using the temp variable.
Instead of a throwing unwrap function, I am proposing a throwing unwrap operator. This operator would work like !, but instead of a fatal error when the value is nil, it would throw.
struct UnwrapError: Error {}
postfix operator ^?
extension Optional {
static postfix func ^?(optional: Optional) throws -> Wrapped {
guard let wrapped = optional else {
throw UnwrapError()
}
return wrapped
}
}
In addition, to round this out, I think it would be helpful to be able to throw arbitrary errors, as a nil value may carry meaning that should be propagated to the rest of the program. Thus there could be a throwing nil coalescing operator, which returns the unwrapped value if non-nil, or throws the specified error if nil.
infix operator ^??
extension Optional {
static func ^??(lhs: Optional, rhs: Error) throws -> Wrapped {
guard let wrapped = lhs else {
throw rhs
}
return wrapped
}
}
Thoughts? I think these would be helpful additions to allow doing something with Optionals while simultaneously exiting early in the case of a nil value — putting the unwrapping, the use, and the exiting early all on one line.
Hopefully this doesn’t distract from the other important conversations happening on the mailing list!
More information about the swift-evolution
mailing list