Based on the feedback on this thread, I'm coming to the following conclusions:

`!!` sends the right semantic message. "Unwrap or die" is an unsafe operation. 
It is based on `!`, the unsafe forced unwrap operator, and not on `??`, the 
safe fallback nil-coalescing operator. Its symbology should therefore follow 
`!` and not `?`. 

The `!!` operator should follow the same semantics as 
`Optional.unsafelyUnwrapped`, which establishes a precedent for this approach:

> "The unsafelyUnwrapped property provides the same value as the forced unwrap 
> operator (postfix !). However, in optimized builds (-O), no check is 
> performed to ensure that the current instance actually has a value. Accessing 
> this property in the case of a nil value is a serious programming error and 
> could lead to undefined behavior or a runtime error."

By following `Optional.unsafelyUnwrapped`, this approach is consistent with 
https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures
 
<https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures>

> "Logic failures are intended to be handled by fixing the code. It means 
> checks of logic failures can be removed if the code is tested enough.
Actually checks of logic failures for various operations, `!`, `array[i]`, `&+` 
and so on, are designed and implemented to be removed
when we use `-Ounchecked`. It is useful for heavy computation like image 
processing and machine learning in which overhead of those checks is not 
permissible."

The right hand side should use a string (or more properly a string autoclosure) 
in preference to using a `Never` bottom type or a `() -> Never` closure. A 
string provides the cleanest user experience, and allows the greatest degree of 
self-documentation. 

- A string is cleaner and more readable to type. It respects DRY, and avoids 
using *both* the operator and the call to `fatalError` or `preconditionFailure` 
to signal an unsafe condition:
`let last = array.last !! “Array guaranteed non-empty" // readable`
than: 
`let last = array.last !! fatalError(“Array guaranteed non-empty”) // 
redundant, violates DRY`

- A string allows the operator *itself* to unsafely fail, just as the unary 
version of `!` does now. It does this with additional feedback to the developer 
during testing, code reading, and code maintenance. The string provides a 
self-auditing in-line annotation of the reason why the forced unwrap has been 
well considered, using a language construct to support this.

- A string disallows a potentially unsafe `Never` call that does not reflect a 
serious programming error, for example:
let last = array.last !! f() // where func f() -> Never { while true {} }

- Although as several list members mention, a `Never` closure solution is 
available today in Swift, so is the `!!` operator solution. Neither one 
requires a fundamental change to the language.

- Pushing forward on this proposal does not in any way reflect on adopting the 
still-desirable `Never` bottom type.

> On Jun 28, 2017, at 12:42 PM, Tony Allevato via swift-evolution 
> <[email protected]> wrote:
> 
> 
> 
> On Wed, Jun 28, 2017 at 11:15 AM Dave DeLong <[email protected] 
> <mailto:[email protected]>> wrote:
>> On Jun 28, 2017, at 10:44 AM, Adrian Zubarev via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Well the main debate is that, we all want early access to a feature that 
>> will be part of Swift as soon as `Never` becomes the bottom type. When this 
>> happens the `??` will automatically support the pitched behavior. Until then 
>> if we all agree that we should add it now in a way that will not break 
>> anything we can simply add an overload to `??` as I previously showed.
>> 
> 
> I believe we should add it now, but I like the recent observation that making 
> ?? suddenly become a potentially crashing operator violates the expectation 
> that ? is an indication of safety.
> 
> ?? does *not* become a potentially crashing operator. The *fatalError* (or 
> whatever else the user chooses to put there) on the right-hand side is the 
> crashing operation.
> 
> 
> On the other hand, the existing semantics of Swift are that ! is always 
> dangerous, so making !! be the a potentially crashing operator is much more 
> consistent with the language.
> 
>> There is no need for `!!` because it will fade in the future. If you think 
>> of `Never` as a bottom type now then `??` will already make total sense. The 
>> default value for T from rhs might be T or Never. 
> 
> I respectfully disagree with your absolute position on this topic. Even with 
> Never as a bottom type in the future, it would still be more convenient for 
> me to type:
> 
> let last = array.last !! “Array must be non-empty"
> 
> … than it ever would be to type:
> 
> let last = array.last ?? fatalError(“Array must be non-empty”)
> 
> 
> There is a very high bar for additions to the standard library—a new operator 
> added to the language is going to be around (1) forever, or (2) indefinitely 
> with some migration cost to users if it's ever removed. Shaving off a few 
> keystrokes doesn't quite meet that bar—especially when an alternative has 
> been shown to work already that provides the same functionality, is more 
> general (not coupled to fatalError or String messages), and that fits better 
> into Swift's design.
> 
> 
> To make sure I'm not being too much of a downer, I would completely support 
> this broader feature being implemented by that alternative: the ?? + 
> autoclosure () -> Never combo. Then once Never does become a true bottom 
> type, I believe it could be removed and the calling code would still *just 
> work*.
> 
>  
> Dave
> 
>> 
>> @erica: the rhs argument should be called something like `noreturnOrError` 
>> and not `defaultValue`. And we should keep in mind that when Never becomes 
>> the bottom type we have to remove that overload from stdlib, because 
>> otherwise it will be ambiguous. 
>> 
>> ---
>> 
>> On the other hand if we tackle a different operator then we should rething 
>> the 'default value operator' because the second ? signals an optional but 
>> not a non-optional or an inplicit unwrapped operator. In that case I 
>> personally thing ?! would make more sense. Unwrap or (non-optional | IUO | 
>> trap/die)
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> Am 28. Juni 2017 um 18:13:18, Tony Allevato via swift-evolution 
>> ([email protected] <mailto:[email protected]>) schrieb:
>> 
>>> It's hard for me to articulate, but "foo !! message" feels a little too 
>>> much like a Perl-ism for my taste. Objectively that's not a great criticism 
>>> on its own, but I just don't like the "smell" of an operator that takes a 
>>> value on one side and a string for error reporting purposes on the other. 
>>> It doesn't feel like it fits the style of Swift. I prefer a version that 
>>> makes the call to fatalError (and thus, any other non-returning handler) 
>>> explicitly written out in code.
>>> 
>>> So, if the language can already support this with ?? and autoclosure/Never 
>>> as was shown above, I'd rather see that added to the language instead of a 
>>> new operator that does the same thing (and is actually less general).
>>> 
>>> On Wed, Jun 28, 2017 at 8:52 AM Jacob Williams via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> I feel that the !! operator would be necessary for indicating that if this 
>>> fails then something went horribly wrong somewhere and we should throw the 
>>> fatalError. This allows the inclusion of optimizations using -Ounchecked 
>>> and is clear that this is an operation that could result in a runtime error 
>>> just like force unwrapping.
>>> 
>>> If we want code clarity and uniformity, then I think !! Is much better than 
>>> ?? because it goes right along with the single ! Used for force unwrapping. 
>>> However, this does depend on if the operator would be returning some kind 
>>> of error that would cause the program to exit.
>>> 
>>> I think the ?? operator should not cause a program to exit early. It goes 
>>> against optional unwrapping principles. I think code could get very 
>>> confusing if some ? would return nil/a default value, and others would be 
>>> causing your program to crash and exit. The ? operators should always be 
>>> classified as safe operations.
>>> 
>>>> On Jun 28, 2017, at 9:41 AM, Ben Cohen via swift-evolution 
>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>> 
>>>> 
>>>>> On Jun 28, 2017, at 8:27 AM, David Hart via swift-evolution 
>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>> 
>>>>> Count me in as a strong proponent of ?? () -> Never. We don't need to 
>>>>> burden the language with an extra operator just for that.
>>>> 
>>>> You could say the same about ??
>>>> 
>>>> The concern that an additional operator (and one that, IMO, fits well into 
>>>> existing patterns) is so burdensome seems way overweighted in this 
>>>> discussion IMO. 
>>>> 
>>>> Adding the operator, and encouraging its use, will help foster better 
>>>> understanding of optionals and legitimate use of force-unwrapping in a way 
>>>> that I don’t think `?? fatalError` could.
>>>> 
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected] <mailto:[email protected]>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to