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. ‘2+2’ is much easier to understand at a glance than having a sentence for each operation.
Also the control flow is completely different. 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). 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: let (a,o1) = Int.addWithOverflow(x,y) guard o1 == false else {throw MyError} let (b,o2) = Int.multiplyWithOverflow(a,z) guard o2 == false else {throw MyError} let (c,o3) = Int.subtractWithOverflow(b,z) guard o3 == false else {throw MyError} return c vs: do{ return try ((x+y)*z)-z }catch _ { throw MyError } Thanks, Jon > On Jan 17, 2017, at 4:22 PM, Xiaodi Wu via swift-evolution > <swift-evolution@swift.org> wrote: > > We already have three ways of handling integer overflow: > > + traps > &+ overflows > addWithOverflow overflows and sets a flag if it does so > > 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. > > 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. > > 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. > > On Tue, Jan 17, 2017 at 18:03 David Waite via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> On Jan 17, 2017, at 1:38 PM, Dave Abrahams via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> It also means, from a purely pragmatic view, that control flow for >> things that are really not reliably recoverable conditions (like index >> out-of-range) is not cleanly separated from control flow for handling >> recoverable things like dropped network conditions, so it can be really >> hard to know that you're reliably shutting down the program when you >> should, and that's not being subverted by some general “recovery” code. > > 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. > > 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. > > 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. > > 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). > > I can envision a future state where: > - system level errors can have atexit/terminate-style shutdown hooks. These > do not support recovery, but can be used to attempt a cleaner shutdown > - 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 > - the possibility of containerization so that runtime errors and certain > system level errors terminate a thread/actor/app domain rather than the whole > process > > -DW > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org <mailto:swift-evolution@swift.org> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution