<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="">I rewrote some code which used NSDecimalNumber to use Decimal and it went from 20 lines of hard to follow code to 2 lines of easy to follow expressions. &nbsp;‘2+2’ is much easier to understand at a glance than having a sentence for each operation.<div class=""><br class=""></div><div class="">Also the control flow is completely different. &nbsp;With one, you have try and then a full equation, and you catch and handle different cases if something went wrong (overflow, underflow, divide by zero). &nbsp;With the other you have to have a guard AFTER each line which uses a previous result (or a pyramid of doom), potentially repeating the same error handling code over and over:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let (a,o1) = Int.addWithOverflow(x,y)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>guard o1 == false else {throw MyError}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let (b,o2) = Int.multiplyWithOverflow(a,z)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>guard o2 == false else {throw MyError}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let (c,o3) = Int.subtractWithOverflow(b,z)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>guard o3 == false else {throw MyError}</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>return c</div><div class=""><br class=""></div><div class="">vs:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>do{</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>&nbsp; &nbsp; return try ((x+y)*z)-z</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}catch _ {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>&nbsp; &nbsp; throw MyError</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon<br class=""><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 17, 2017, at 4:22 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class="">We already have three ways of handling integer overflow:<br class=""><br class="">+ traps<br class="">&amp;+ overflows<br class="">addWithOverflow overflows and sets a flag if it does so<br class=""><br class="">This supports all possible ways of handling the issue: you can trap, you can get a result and not care about the overflow flag, or you can get the result *and* the overflow flag. You can even discard the result and work with only the flag.<br class=""><br class="">I don't see how this doesn't meet exactly what you and Jonathan Hull describe: it is opt-in, optional for callers, and does not propagate. It doesn't require try or any other cumbersome syntax, and it allows you to just compute the operation first and handle the overflow later only if it occurs.<br class=""><br class="">For array indexing, there is an outstanding proposal for more lenient subscripts. In the meantime, you can trivially implement your own.  Such a facility would also behave according to your stated requirements.<br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Jan 17, 2017 at 18:03 David Waite via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br 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="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Jan 17, 2017, at 1:38 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-1010993449595040349Apple-interchange-newline gmail_msg"><div class="gmail_msg"><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!important" class="gmail_msg">It also means, from a purely pragmatic view, that control flow for</span><br 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" class="gmail_msg"><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!important" class="gmail_msg">things that are really not reliably recoverable conditions (like index</span><br 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" class="gmail_msg"><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!important" class="gmail_msg">out-of-range) is not cleanly separated from control flow for handling</span><br 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" class="gmail_msg"><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!important" class="gmail_msg">recoverable things like dropped network conditions, so it can be really</span><br 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" class="gmail_msg"><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!important" class="gmail_msg">hard to know that you're reliably shutting down the program when you</span><br 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" class="gmail_msg"><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!important" class="gmail_msg">should, and that's not being subverted by some general “recovery” code.</span><br 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" class="gmail_msg"></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">Agreed. The “try” syntax is part of a decision to use errors to represent conditions recoverable by business logic. This might be a network connection closed, but shouldn’t be used for conditions like memory allocation failed, a KILL signal, or detection of corrupted data within an application bundle.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In the middle are avoidable runtime errors like array indexing out-of-bounds and math overflow. Some business logic might care about these, in particular logic which deals with arbitrary user input. However, using ‘try’ syntax would result in both an explosion of needing to specify try in expressions, and in errors which can’t really be recovered in typical business logic.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I see this as three regions of error conditions - system level errors that the developer isn’t expected to try and recover from, application-level errors that the developer is likely going to want to control the behavior of, and in between the runtime errors which some logic might care about, but which in most cases should be treated as a system level error.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Java roughly has Error, Exception, and RuntimeException to correspond to these, with a few differences which I generally consider to be flaws in the Java language (RuntimeException is under Exception, RuntimeExceptions percolate up the entire stack rather than being escalated to Errors if unhandled).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I can envision a future state where:</div><div class="gmail_msg">- system level errors can have atexit/terminate-style shutdown hooks. These do not support recovery, but can be used to attempt a cleaner shutdown</div><div class="gmail_msg">- functions which emit runtime errors (such as math overflow) can support a call form which returns an error rather than precondition failure, but it is opt in and optional for callers. The runtime errors do not propagate automatically, and callers which do not request it get precondition failures</div><div class="gmail_msg">- the possibility of containerization so that runtime errors and certain system level errors terminate a thread/actor/app domain rather than the whole process</div></div><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg">-DW</div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>