[swift-evolution] Failable arithmetic

Joe Groff jgroff at apple.com
Fri Dec 4 18:18:23 CST 2015

> On Dec 4, 2015, at 4:13 PM, Chris Lattner <clattner at apple.com> wrote:
>
>>
>> On Dec 4, 2015, at 2:40 PM, Brent Royal-Gordon <brent at architechies.com> wrote:
>>
>> Currently, Swift has three ways to handle potential overflows and other errors in arithmetic:
>>
>> 	// 1: Crashes
>> 	Int.max + 1
>>
>> 	// 2: Returns the wrong answer (Int.min in this case)
>> 	Int.max &+ 1
>>
>> 	// 3: Returns a tuple with the value of &+ and a boolean indicating whether it overflowed
>>
>> 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.
>>
>> Therefore, I propose that we add failable arithmetic operators (e.g. +?). These return nil on overflow and the result on non-overflow.
>>
>> 	1 +? 1			// => Optional(1)
>> 	Int.max +? 1		// => nil
>>
>> 	1 -? 1			// => Optional(0)
>> 	Int.min -? 1		// => nil
>>
>> 	1 /? 1			// => Optional(1)
>> 	1 /? 0			// => nil
>>
>> 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:
>
> This is similar to the request for a “force unwrap” operator that is catch’able.  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.  This will allow them to chain properly and compose correctly with other operations.
>
> There are other questions in this family: we’ve discussed adding saturating integer arithmetic operators as a way to handle this.  We have also discussed the idea of having “-ffast-math” floating point operators as well.  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 :-)
>
> Another way to think about this as a need to modify the behavior of failing operators.  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:
>
>  {
>      #pragma failure_should_throw    // again, #pragma is really not the right way to spell this :-)
>      try t = m * x + c
>  }
>
> and have the operators magically do the right thing?  Then you could generalize the behavior to support other families by using an english word to describe the semantics.

This is a place where scoped `import` might help too. For instance, you could import a module with throwing variants of the operators:

{
import ThrowingOnOverflow
try t = m * x + c
}

-Joe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151204/a3e20348/attachment.html>