<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 28, 2017, at 10:49 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Wed, Jun 28, 2017 at 10:33 PM, Paul Cantrell <span dir="ltr" class=""><<a href="mailto:cantrell@pobox.com" target="_blank" class="">cantrell@pobox.com</a>></span> wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Jun 28, 2017, at 9:50 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank" class="">xiaodi.wu@gmail.com</a>> wrote:</div><br class="m_2589842927366661829Apple-interchange-newline"><div class=""><div dir="ltr" class="">On Wed, Jun 28, 2017 at 8:54 PM, Paul Cantrell <span dir="ltr" class=""><<a href="mailto:paul@bustoutsolutions.com" target="_blank" class="">paul@bustoutsolutions.com</a>></span> wrote:<br class=""><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 style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class=""><span class="m_2589842927366661829gmail-"><blockquote type="cite" class=""><div class="">On Jun 28, 2017, at 8:32 PM, Xiaodi Wu via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">I would like to see an example where this string plausibly makes the difference between having to hunt down the code and not have to do so. I do not believe that "array must not be empty" or "array guaranteed non-empty" is such an example, and I cannot myself imagine another scenario where it would make such a difference.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span>You needn’t imagine. There was one up-thread:<div class=""><br class=""></div><div class=""><span style="font-family:HelveticaNeue" class=""> let paramData = params.data(using: String.Encoding.ascii)!</span><br style="font-family:HelveticaNeue" class=""></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div><div class=""><span style="font-family:HelveticaNeue" class="">Huh? Why is force unwrap safe here? OK, the code plainly says the author thinks that `params` must already be ASCII, but why is that a safe assumption? What reasoning lead to that? What other sections of the code does that reasoning depend on? If we get a crash on this line of code, what chain of assumptions should we follow to discover the change that broke the original author’s reasoning behind the force unwrap?</span></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div><div class=""><span style="font-family:HelveticaNeue" class="">This is a job for a comment:</span></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div><div class=""><div class=""><span style="font-family:HelveticaNeue" class=""> </span><span style="font-family:HelveticaNeue" class="">let paramData =</span><span style="font-family:HelveticaNeue" class=""> </span><span style="font-family:HelveticaNeue" class="">params.data(using: String.Encoding.ascii)! // </span><span style="font-family:HelveticaNeue" class="">params</span><span style="font-family:HelveticaNeue" class=""> is </span><span style="font-family:HelveticaNeue" class="">URL-escaped, thus already</span><span style="font-family:HelveticaNeue" class=""> ASCII</span></div><div class=""><font face="HelveticaNeue" class=""><br class=""></font></div><div class=""><font face="HelveticaNeue" class="">Aha, it’s URL escaped.</font></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div><div class=""><span style="font-family:HelveticaNeue" class="">That comment does not repeat information already stated in the code itself. It does what any good comment does: it explains </span><span style="font-family:HelveticaNeue" class="">intent, </span><font face="HelveticaNeue" class="">context, and rationale. It doesn’t restate _what_, but rather explains _why_.</font></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div><div class=""><font face="HelveticaNeue" class="">For those who appreciate comments like that, this proposal simply allows them to surface at runtime:</font></div><div class=""><span style="font-family:HelveticaNeue" class=""><br class=""></span></div></div><div class=""><span style="font-family:HelveticaNeue" class=""> </span><span style="font-family:HelveticaNeue" class="">let paramData =</span><span style="font-family:HelveticaNeue" class=""> </span><span style="font-family:HelveticaNeue" class="">params</span><span style="font-family:HelveticaNeue" class="">.data(using: String.Encoding.ascii) !! "</span><span style="font-family:HelveticaNeue" class="">params</span><span style="font-family:HelveticaNeue" class=""> is </span><span style="font-family:HelveticaNeue" class="">URL-escaped, thus already</span><span style="font-family:HelveticaNeue" class=""> ASCII"</span></div><div class=""><br class=""></div><div class="">And those who see no value in such a runtime message — and thus likely also see no value such a comment — are free not to use either.</div></div></div></blockquote><div class=""><br class=""></div><div class="">If this is the most convincing example, then I'd actually be adamantly _against_ such an operator (where now I'm merely skeptical and would like to see evidence of usefulness). This example is, quite simply, _wrong_. Here's why:</div><div class=""><br class=""></div><div class="">First, if force unwrapping fails, the message should explain why it failed: the reason why it failed is _not_ because it's URL-escaped and _not_ because it's ASCII, but rather because it's **not** ASCII.</div></div></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">Fine, then:</div><div class=""><br class=""></div><div class=""> let paramData = params.data(using: String.Encoding.ascii) !! “params must be URL-escaped, and thus ASCII"</div><div class=""><br class=""></div><div class=""><div class="">…or format the runtime message to fit that style of phrasing:</div><div class=""><br class=""></div><div class=""> fatal error: unexpectedly found nil while unwrapping an Optional value</div><div class=""><span class=""> Failing underlying assumption:</span></div><span class=""><div class=""><span class=""> </span><span style="font-family:HelveticaNeue" class="">params</span><span style="font-family:HelveticaNeue" class=""> is </span><span style="font-family:HelveticaNeue" class="">URL-escaped, thus already</span><span style="font-family:HelveticaNeue" class=""> ASCII</span></div></span></div> Current stack trace:</div><div class=""> …<span class=""><br class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">Second, even supposing the wording were fixed, it's at best not more useful than `!` and at worst misleading.</div></div></div></div></blockquote><div class="">…</div></span><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">If the error message is "params not URL-escaped," then it's misleading, as that's not at all what the LHS is actually asserting: it can be unwrapped *whether or not* it's URL-escaped and it only matters that it's ASCII.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Yes, of _course_ it’s not what the LHS is actually asserting. That is precisely the point of having a message. There is pertinent information not already present in the code.</div></div></div></blockquote><div class=""><br class=""></div><div class="">See below.</div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><div class="">The message describes an invariant not captured by the type system. In other words, the author of this code believes they have guaranteed something that the compiler itself cannot check. Thus this statement is exactly backwards:</div><span class=""><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">You **absolutely cannot** proceed from this point in the code assuming that `paramData` is a URL-escaped string.</div></div></div></div></blockquote><br class=""></div></span><div class="">The author of this code is telling you they have _already_ proceeded from this point assuming that `paramData` is URL-escaped.</div></div></div></blockquote><div class=""><br class=""></div><div class="">No, the author proceeded from a previous point assuming that `params` is URL-escaped. The act of unwrapping does not demarcate the transition between where `params` is assumed to be URL-escaped and where it is not.</div></div></div></div></div></blockquote><div><br class=""></div><div>Well duh. But that’s not what the message conveys.</div><div><br class=""></div><div>Read x !! y as “x! /* which is guaranteed to succeed because y */”.</div><div><br class=""></div><div>P</div><div><br class=""></div></div></body></html>