[swift-evolution] [Pitch] Throwing unwrap operators

Erica Sadun erica at ericasadun.com
Sun Jul 30 13:37:55 CDT 2017


From 2016:

See: https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160404/014272.html <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160404/014272.html>
and https://gist.github.com/erica/5a26d523f3d6ffb74e34d179740596f7 <https://gist.github.com/erica/5a26d523f3d6ffb74e34d179740596f7>

-- E

> On Jul 30, 2017, at 12:30 PM, Gor Gyolchanyan via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 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
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170730/e0b7d692/attachment.html>


More information about the swift-evolution mailing list