<div dir="ltr">On Wed, Jun 28, 2017 at 5:05 PM, ilya via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr">I'm unconvinced. We already have the perfectly functional "unwrap or die" operator, that is, the <b>force unwrap</b> <b>! </b>operator. <div><br></div><div>Can it be improved? Definitely. If the developer wants to provide some context for a possible fatal error, it would be great for the language to give the tools to express it. </div><div><br></div><div>Perhaps we can examine a more general problem of improving debugging output for symbols and operations. We can already associate some information with functions and classes using the documentation markup. Why not build on that?</div><div><br></div><div>One could, for example, extend the existing<b> documentation markup sign</b> <b>///</b> to pick up text as force unwrap messages:</div><div><br></div><div><div><span style="font-family:Menlo;font-size:11px"> `let last = array.last! /// Array guaranteed non-empty`</span></div></div></div></blockquote><div><br></div><div>I did not call this out initially, but I feel like this is an important point to address:</div><div><br></div><div>In the initial example, repeated here in largely identical form, the desired comment is "array must be non-empty." In what way does that provide more information than a bare `!`?</div><div><br></div><div>To my mind, when you unwrap an optional, the reason for failure is evident: you expected some value, but you got no value. Moreover, the document about error handling design in Swift (available in the GitHub repo) explains that functions should return nil (vs. throwing) _when there's only one (obvious) way to fail_. Therefore, when you force-unwrap the subsequent result and trap, there's been an obvious failure when you expected none. As far as I can see, the overall logic behind such a design works together to obviate the need for more explanation when force-unwrapping. The example above demonstrates this point very well: when there is no last element of an array, the array must be empty--this is, I'm sure all will agree, plainly obvious and wisely modeled with an optional--and therefore, if you encounter a fatal error unwrapping the result, you expected a non-empty array and instead encountered an empty array.<br></div><div><br></div><div>As a result, I find Ilya's point to be very illuminating that `!` is _the_ force-unwrap-or-die operator. Can someone come up with a more plausible motivation for an additional operator?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div></div><div>Best,</div>Ilya.</div><div><div class="gmail-h5"><div><br><div class="gmail_quote"><div dir="ltr">On Wed, Jun 28, 2017 at 11:00 PM Erica Sadun via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Based on the feedback on this thread, I'm coming to the following conclusions:</div><div><br></div><div>`!!` sends the <i>right semantic message</i>. "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 `?`. </div><div><br></div><div>The `!!` operator should follow the same semantics as `<font face="Menlo" style="font-size:11px">Optional.unsafelyUnwrapped</font>`, which establishes a precedent for this approach:</div><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div>> "<i>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.</i>"</div></blockquote><div><br></div><div>By following `<font face="Menlo" style="font-size:9px">Optional.unsafelyUnwrapped</font>`, this approach is consistent with <a href="https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#logic-failures" target="_blank">https://github.com/apple/<wbr>swift/blob/master/docs/<wbr>ErrorHandlingRationale.rst#<wbr>logic-failures</a></div></div><div style="word-wrap:break-word"><div><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><i><span style="font-family:Palatino-Roman">> "Logic failures are intended to be handled by fixing the code. It means </span><span style="font-family:Palatino-Roman">checks of logic failures can be removed if the code is tested enough.</span><br style="font-family:Palatino-Roman"><span style="font-family:Palatino-Roman">Actually checks of logic failures for various operations, `!`, </span><span style="font-family:Palatino-Roman">`array[i]`, `&+` and so on, are designed and implemented to be removed</span><br style="font-family:Palatino-Roman"><span style="font-family:Palatino-Roman">when we use `-Ounchecked`. It is useful for heavy computation like </span><span style="font-family:Palatino-Roman">image processing and machine learning in which overhead of those </span><span style="font-family:Palatino-Roman">checks is not permissible."</span></i></div></blockquote><div><br></div></div><div style="word-wrap:break-word"><div>The right hand side should use a string (or more properly a string autoclosure) in preference to using a `<font face="Menlo" style="font-size:11px">Never</font>` bottom type or a `<font face="Menlo" style="font-size:11px">() -> Never</font>` closure. A string provides the cleanest user experience, and allows the greatest degree of self-documentation. </div><div><br></div><div>- 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:</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-family:Menlo;font-size:11px">`let last = array.last !! “Array guaranteed non-empty" // readable`</span></div></blockquote><div>than: </div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-family:Menlo;font-size:11px">`let last = array.last !! fatalError(“Array </span><span style="font-family:Menlo;font-size:11px">guaranteed</span><span style="font-family:Menlo;font-size:11px"> <wbr>non-empty”) // redundant, violates DRY`</span></div><div><br></div></blockquote><div>- A string allows the operator *<i>itself</i>* 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.</div><div><br></div><div>- A string disallows a potentially unsafe `Never` call that does not reflect a serious programming error, for example:</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><span style="font-family:Menlo;font-size:11px">let last = array.last !! f() // where </span><span style="font-family:Menlo;font-size:11px">func f() -> Never { while true {} }</span></div></blockquote><div><br></div><div>- 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.</div><div><br></div><div>- Pushing forward on this proposal does not in any way reflect on adopting the still-desirable `Never` bottom type.</div></div><div style="word-wrap:break-word"><div><br></div><div><blockquote type="cite"><div>On Jun 28, 2017, at 12:42 PM, Tony Allevato via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="gmail-m_-1333435602167744256m_8091643394762353919Apple-interchange-newline"><div><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Jun 28, 2017 at 11:15 AM Dave DeLong <<a href="mailto:delong@apple.com" target="_blank">delong@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><blockquote type="cite"><div>On Jun 28, 2017, at 10:44 AM, Adrian Zubarev via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="gmail-m_-1333435602167744256m_8091643394762353919m_-2274859510633634742Apple-interchange-newline"><div><div>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.<div><br></div></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word"><div><div>I believe we should add it now, but I like the recent observation that making <font face="Menlo"><span style="font-size:11px">??</span></font> suddenly become a potentially crashing operator violates the expectation that <font face="Menlo"><span style="font-size:11px">?</span></font> is an indication of safety.</div></div></div></blockquote><div><br></div><div>?? 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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div><br></div><div>On the other hand, the existing semantics of Swift are that <font face="Menlo"><span style="font-size:11px">!</span></font> is always dangerous, so making <font face="Menlo"><span style="font-size:11px">!!</span></font> be the a potentially crashing operator is much more consistent with the language.</div></div></div><div style="word-wrap:break-word"><div><br><blockquote type="cite"><div><div><div>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. </div></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word"><div><div>I respectfully disagree with your absolute position on this topic. Even with <font face="Menlo"><span style="font-size:11px">Never</span></font> as a bottom type in the future, it would <i>still</i> be more convenient for me to type:</div><div><br></div><div><font face="Menlo"><span style="font-size:11px">let last = array.last !! “Array must be non-empty"</span></font></div><div><br></div><div>… than it ever would be to type:</div><div><br></div><div><font face="Menlo"><span style="font-size:11px">let last = array.last ?? fatalError(“Array must be non-empty”)</span></font></div></div></div><div style="word-wrap:break-word"><div><div><br></div></div></div></blockquote><div><br></div><div>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.</div><div><br></div><div><br></div><div>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*.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div><div></div><div>Dave</div></div></div><div style="word-wrap:break-word"><div><br><blockquote type="cite"><div><div><div><br></div><div>@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. </div><div><br></div><div>---</div><div><br></div><div>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)<br> <br><div class="gmail-m_-1333435602167744256m_8091643394762353919m_-2274859510633634742bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div><p class="gmail_quote">Am 28. Juni 2017 um 18:13:18, Tony Allevato via swift-evolution (<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>) schrieb:</p> <blockquote type="cite" class="gmail_quote"><span><div><div></div><div>
<div>
<div>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.<br>
<br>
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).</div>
</div>
<div>
<div><br>
<div class="gmail_quote">
<div>On Wed, Jun 28, 2017 at 8:52 AM Jacob Williams via
swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>
wrote:<br></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div style="word-wrap:break-word">
<div>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.</div>
<div><br></div>
<div>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.</div>
<div><br></div>
<div>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.</div>
</div>
<div style="word-wrap:break-word">
<div><br>
<div>
<blockquote type="cite">
<div>On Jun 28, 2017, at 9:41 AM, Ben Cohen via swift-evolution
<<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div>
<br class="gmail-m_-1333435602167744256m_8091643394762353919m_-2274859510633634742m_2866777249939610229m_1922728200947037084Apple-interchange-newline">
<div>
<div style="word-wrap:break-word"><br>
<div>
<blockquote type="cite">
<div>On Jun 28, 2017, at 8:27 AM, David Hart via swift-evolution
<<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div>
<br class="gmail-m_-1333435602167744256m_8091643394762353919m_-2274859510633634742m_2866777249939610229m_1922728200947037084Apple-interchange-newline">
<div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline">
Count me in as a strong proponent of ?? () -> Never. We don't
need to burden the language with an extra operator just for
that.</span><br class="gmail-m_-1333435602167744256m_8091643394762353919m_-2274859510633634742m_2866777249939610229m_1922728200947037084Apple-interchange-newline">
</div>
</blockquote>
</div>
<br>
<div>You could say the same about ??</div>
<div><br></div>
<div>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. </div>
<div><br></div>
<div>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.</div>
<div><br></div>
<div><br></div>
</div>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</div>
</blockquote>
</div>
<br></div>
</div>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</blockquote>
</div>
</div>
</div>
______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></div></span></blockquote>
</div></div>______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></blockquote></div></div></blockquote></div></div>
______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></blockquote></div><br></div>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
</blockquote></div></div></div></div></div>
<br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div></div>