<div dir="ltr">On Wed, Jun 28, 2017 at 9:50 PM, Xiaodi Wu <span dir="ltr">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</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"><span class="gmail-">On Wed, Jun 28, 2017 at 8:54 PM, Paul Cantrell <span dir="ltr">&lt;<a href="mailto:paul@bustoutsolutions.com" target="_blank">paul@bustoutsolutions.com</a>&gt;</span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-"><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><br></div><div><span class="gmail-m_4349516048972906833gmail-"><blockquote type="cite"><div>On Jun 28, 2017, at 8:32 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>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 &quot;array must not be empty&quot; or &quot;array guaranteed non-empty&quot; 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><br></div></span>You needn’t imagine. There was one up-thread:<div><br></div><div><span style="font-family:HelveticaNeue">  let paramData = params.data(using: String.Encoding.ascii)!</span><br style="font-family:HelveticaNeue"></div><div><span style="font-family:HelveticaNeue"><br></span></div><div><span style="font-family:HelveticaNeue">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><span style="font-family:HelveticaNeue"><br></span></div><div><span style="font-family:HelveticaNeue">This is a job for a comment:</span></div><div><span style="font-family:HelveticaNeue"><br></span></div><div><div><span style="font-family:HelveticaNeue">  </span><span style="font-family:HelveticaNeue">let paramData =</span><span style="font-family:HelveticaNeue"> </span><span style="font-family:HelveticaNeue">params.data(using: String.Encoding.ascii)!  // </span><span style="font-family:HelveticaNeue">params</span><span style="font-family:HelveticaNeue"> is </span><span style="font-family:HelveticaNeue">URL-escaped, thus already</span><span style="font-family:HelveticaNeue"> ASCII</span></div><div><font face="HelveticaNeue"><br></font></div><div><font face="HelveticaNeue">Aha, it’s URL escaped.</font></div><div><span style="font-family:HelveticaNeue"><br></span></div><div><span style="font-family:HelveticaNeue">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">intent, </span><font face="HelveticaNeue">context, and rationale. It doesn’t restate _what_, but rather explains _why_.</font></div><div><span style="font-family:HelveticaNeue"><br></span></div><div><font face="HelveticaNeue">For those who appreciate comments like that, this proposal simply allows them to surface at runtime:</font></div><div><span style="font-family:HelveticaNeue"><br></span></div></div><div><span style="font-family:HelveticaNeue">  </span><span style="font-family:HelveticaNeue">let paramData =</span><span style="font-family:HelveticaNeue"> </span><span style="font-family:HelveticaNeue">params</span><span style="font-family:HelveticaNeue">.data(using: String.Encoding.ascii) !! &quot;</span><span style="font-family:HelveticaNeue">params</span><span style="font-family:HelveticaNeue"> is </span><span style="font-family:HelveticaNeue">URL-escaped, thus already</span><span style="font-family:HelveticaNeue"> ASCII&quot;</span></div><div><br></div><div>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><br></div></span><div>If this is the most convincing example, then I&#39;d actually be adamantly _against_ such an operator (where now I&#39;m merely skeptical and would like to see evidence of usefulness). This example is, quite simply, _wrong_. Here&#39;s why:</div><div><br></div><div>First, if force unwrapping fails, the message should explain why it failed: the reason why it failed is _not_ because it&#39;s URL-escaped and _not_ because it&#39;s ASCII, but rather because it&#39;s **not** ASCII.</div><div><br></div><div>Second, even supposing the wording were fixed, it&#39;s at best not more useful than `!` and at worst misleading. If the error message is &quot;params not ASCII-encoded&quot; then it restates the code itself. If the error message is &quot;params not URL-escaped,&quot; then it&#39;s misleading, as that&#39;s not at all what the LHS is actually asserting: it can be unwrapped *whether or not* it&#39;s URL-escaped and it only matters that it&#39;s ASCII. You **absolutely cannot** proceed from this point in the code assuming that `paramData` is a URL-escaped string.</div></div></div></div></blockquote><div><br></div><div>At the risk of belaboring the point, allow me to develop this intuition further. The second argument in a precondition is classically phrased &quot;X must be Y&quot; or &quot;X is not Y,&quot; and it serves two purposes (as I understand it). If the precondition fails, then the reader understands that it is because X is not Y. If the precondition succeeds, the reader is assured that the precondition has tested that X is in fact Y.</div><div><br></div><div>Two uses have been advanced for the RHS of the proposed operator. The first is, in the case of failure, to explain the failure without requiring surrounding code context. The second is to explain to the reader, in the context of the code, why success should be assured. But, this does not imply that the underlying reason why success is assured is in turn also true if the force unwrapping operation succeeds.</div><div><br></div><div>_The only error message_ that satisfies both of the purposes of a precondition message in the case of a force unwrap is &quot;X is not nil.&quot; In your example, &quot;params must be URL-escaped&quot; cannot fulfill both of these uses, because successful unwrapping is not preconditioned on params being in fact URL-escaped. OTOH, &quot;params must be ASCII-encoded&quot; is not necessary as a message because it is implied in the meaning of `!`.</div></div></div></div>