[swift-evolution] [Pitch] Throwing unwrap operators

Gor Gyolchanyan gor.f.gyolchanyan at icloud.com
Sun Jul 30 13:30:40 CDT 2017


I like the general direction where this is going, but I haven’t settled on an opinion regarding its appearance yet.
I’ve argued before that the gap between optionals and errors should be closed by making it easy to swift from optionals to non-optionals with throwing.
The “unwrap-or-die” idea discussed earlier is very similar to this.

In the end, I think all optional, throwing and fatalError-related proposals have to be united and carefully considered as an overarching proposal to extend and complete Swift’s representation of “less-than-normal” situations.

> On Jul 30, 2017, at 9:25 PM, Robert Bennett via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 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!
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list