<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 Dec 4, 2015, at 4:13 PM, Chris Lattner &lt;<a href="mailto:clattner@apple.com" class="">clattner@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline">On Dec 4, 2015, at 2:40 PM, Brent Royal-Gordon &lt;<a href="mailto:brent@architechies.com" class="">brent@architechies.com</a>&gt; wrote:<br class=""><br class="">Currently, Swift has three ways to handle potential overflows and other errors in arithmetic:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// 1: Crashes<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Int.max + 1<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// 2: Returns the wrong answer (Int.min in this case)<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Int.max &amp;+ 1<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// 3: Returns a tuple with the value of &amp;+ and a boolean indicating whether it overflowed<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Int.addWithOverflow(Int.max, 1)<br class=""><br class="">The problem is, if you want to handle overflows in some simple way, none of these are very good. 1 terminates your app, 2 gives the wrong answer, and 3 is very awkward to use. If you’re, for instance, working with numbers input by the user or downloaded from the Internet, you don’t want 1 or 2, and 3 is a major pain. You’re not looking to figure out exactly what went wrong; you just want to show the user “Arithmetic error” or something, rather than crashing or giving a wildly incorrect answer.<br class=""><br class="">Therefore, I propose that we add failable arithmetic operators (e.g. +?). These return nil on overflow and the result on non-overflow.<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>1 +? 1<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; Optional(1)<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Int.max +? 1<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; nil<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>1 -? 1<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; Optional(0)<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Int.min -? 1<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; nil<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>1 /? 1<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; Optional(1)<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>1 /? 0<span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>// =&gt; nil<br class=""><br class="">One important consideration is that you ought to be able to chain such operations together into expressions like "m *? x +? c”. The simplest way to do this would be to make these operators take optional arguments; then the implementations would all look something like this:<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">This is similar to the request for a “force unwrap” operator that is catch’able. &nbsp;If we were to do something along these lines, I’d rather see these be modeled as operators that can throw, rather than operators that produce an optional. &nbsp;This will allow them to chain properly and compose correctly with other operations. &nbsp;</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">There are other questions in this family: we’ve discussed adding saturating integer arithmetic operators as a way to handle this. &nbsp;We have also discussed the idea of having “-ffast-math” floating point operators as well. &nbsp;If you take this to the logical conclusion, you end up with large families of operators, all distinguished by magic sigil families that no one can remember :-)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Another way to think about this as a need to modify the behavior of failing operators. &nbsp;This is not intended as a syntax proposal (just to get the idea across), but wouldn’t it be cool to be able to do:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&nbsp;{</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#pragma failure_should_throw &nbsp;&nbsp;&nbsp;// again, #pragma is really not the right way to spell this :-)</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try t = m * x + c</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">&nbsp;}</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">and have the operators magically do the right thing? &nbsp;Then you could generalize the behavior to support other families by using an english word to describe the semantics. &nbsp;</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote></div><br class=""><div class="">This is a place where scoped `import` might help too. For instance, you could import a module with throwing variants of the operators:</div><div class=""><br class=""></div><div class="">{</div><div class="">&nbsp; import ThrowingOnOverflow</div><div class="">&nbsp; try t = m * x + c</div><div class="">}</div><div class=""><br class=""></div><div class="">-Joe</div></body></html>