[swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

Dave DeLong delong at apple.com
Fri Jun 30 12:02:08 CDT 2017

These are good points, Brent.

> On Jun 29, 2017, at 11:24 PM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
>> On Jun 27, 2017, at 10:16 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> Using an operator to provide feedback on the context of a failed unwrap has become a commonly implemented approach in the Swift developer Community. What are your thoughts about adopting this widely-used operator into the standard library?
>> guard !lastItem.isEmpty else { return }
>> let lastItem = array.last !! "Array must be non-empty"
>> Details here:  https://gist.github.com/erica/423e4b1c63b95c4c90338cdff4939a9b <https://gist.github.com/erica/423e4b1c63b95c4c90338cdff4939a9b>
>> Thank you for your thoughtful feedback, -- E
> Finally found a few minutes to read this thread.
> I'm a big fan of the `Never`-based approach. (I was before, but I am more so now.) Here are the points I can see in its favor:
> 1. It is extremely clear about what's happening—`!!` is another random operator to learn, but `fatalError(_:)` or `preconditionFailure(_:)` are fairly self-explanatory, and `??` is something you might already be using.

!! is also clear about what’s happening, because it’s just like the existing ! operator.

> 2. It allows you to control the optimization behavior by using `fatalError`, `preconditionFailure`, or `assertionFailure` as desired.

Yep. That’s cool.

> 3. If we later change `throw` from being a statement to being a `Never`-returning expression, you could use `throw` on the right-hand side of `??`.

Neat idea. 👍 

> 4. It supports other `Never`-returning operations, like `abort()` or `exit(_:)` or your custom `usage()` function, on the right side of `??`.

Yep. That’s cool.

> 5. It supports file-and-line error reporting without having to add any new features; `!!` could not do this because an operator can't have extra, defaulted parameters to carry the file and line.

Erica’s proposal addresses this. Allowing operator functions to accept more than 2 parameters that all have default arguments looks like it would be a pretty straight-forward and non-controversial change. It would also allow the FRP crowd to make their <~ and |> and ಠ_ಠ and (╯°□°)╯︵ ┻━┻ operators all capture the #file and #line they’re used on, which would make debugging those style of apps much easier.

> 6. It harmonizes with the eventual idea of making `Never` a universal bottom type, but we don't actually have to implement that today, because we can just overload `??` for now.

Yep. That’s cool.

> Against these advantages, the only one I can see for `!!` is that it is terse. Terseness is good, especially for a feature which is competing with the single-character postfix `!` operator, but I can't help but be drawn to the flexibility and power of `??` with a `Never` expression on the right-hand side.

I would argue that terseness is a goal of Swift. If it weren’t, we shouldn’t have [Element] as sugar syntax for Array<Element>, or even a bunch of our operators (postfix !, postfix ?, overflow checking operators, nil coalescing, etc). 

IMO, having both !! that takes an error message and ?? that takes a () → Never seem like worthwhile goals. The former allows me to be terse, yet still expressive, and the latter allows me the customization to do what I want for whatever is contextually appropriate in my situation.

I don’t think anyone is arguing that ?? () → Never isn’t useful. The purpose of this proposal is to put forward and defend the claim that “!! String” is also useful and meets the barrier to entry in to the Standard Library.


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

More information about the swift-evolution mailing list