On Jun 24, 2016, at 3:03 PM, Nicola Salmoria <nicola.salmoria@gmail.com> wrote:
On Fri, Jun 24, 2016 at 11:45 PM, Max Moiseev <moiseev@apple.com <mailto:moiseev@apple.com>> wrote:
However, division by 0 isn't an overflow: it's an undefined operation. I find it somewhat surprising that dividedWithOverflow/remainderWithOverflow allow attempting this operation.
I tried to say that in my previous email. I agree that division by zero is NOT the overflow and should probably be handled differently if only for a better error message.
To me, the intuitive semantics of the WithOverflow methods are "perform the operation, and if the result doesn't fit in the given type, return a truncated result and an overflow flag". This is not what happens when dividing by 0, because the result simply doesn't exist.
I think I would prefer if rhs != 0 was documented as an explicit precondition of the division and remainder operations, and dividedWithOverflow/remainderWithOverflow trapped because of precondition failure.
That’s exactly how it is implemented in the prototype now.
Now I'm confused. Isn't this line of the gyb returning .overflow when the divisor is 0?
https://github.com/apple/swift/blob/master/test/Prototypes/Integers.swift.gyb#L793
Also, the current version of Swift doesn't trap either:
let z = 0
print(Int.divideWithOverflow(1, z)) // (0, true)
print(Int.remainderWithOverflow(1, z)) // (0, true)
interestingly, you need to put 0 in a variable otherwise the compiler rejects the lines.
If it is desirable that the WithOverflow methods never trap, then I think it would be better to add a `divisionByZero` case to the ArithmeticOverflow enum and return that instead of the generic `overflow`.
Nice idea, but I don’t think it is really required that WithOverflow methods should never fail. The main idea behind these methods is to allow for 2 versions of arithmetic operations: one that traps on overflow and an unsafe one, that simply discards the overflow flag returning the partial result. Both of these however should, in my opinion, trap in a truly exceptional case of division by 0.
That would be my preference too. Thanks!
Nicola
Thanks for your comments, Nicola!
Max
On Jun 23, 2016, at 11:06 PM, Nicola Salmoria <nicola.salmoria@gmail.com <mailto:nicola.salmoria@gmail.com>> wrote:
On Fri, Jun 24, 2016 at 12:12 AM, Max Moiseev <moiseev@apple.com <mailto:moiseev@apple.com>> wrote:
Hi Nicola,
> For these reasons, I think it would make sense to explicitly request that
> the remainder operation never traps, and remove the overflow variants.
It will still trap when you divide by 0. But in that case falling back to the same generic overflow logic is not the best idea.
I agree that remainder is special, let me see what I can do about it.
LOL, yes of course, I forgot about the obvious trapping case.
However, division by 0 isn't an overflow: it's an undefined operation. I find it somewhat surprising that dividedWithOverflow/remainderWithOverflow allow attempting this operation.
To me, the intuitive semantics of the WithOverflow methods are "perform the operation, and if the result doesn't fit in the given type, return a truncated result and an overflow flag". This is not what happens when dividing by 0, because the result simply doesn't exist.
I think I would prefer if rhs != 0 was documented as an explicit precondition of the division and remainder operations, and dividedWithOverflow/remainderWithOverflow trapped because of precondition failure.
If it is desirable that the WithOverflow methods never trap, then I think it would be better to add a `divisionByZero` case to the ArithmeticOverflow enum and return that instead of the generic `overflow`.
Thanks,
Nicola
Thanks,
Max
> On Jun 23, 2016, at 2:38 PM, Nicola Salmoria via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Max Moiseev via swift-evolution <swift-evolution@...> writes:
>
>>> For FixedWidthInteger#dividedWithOverflow/remainderWithOverflow, under
> what situations would
>> you have an overflow? I could only come up with something like
> Int.min.dividedWithOverflow(-1).
>> If you look at the prototype here:
>>
> https://github.com/apple/swift/blob/master/test/Prototypes
> /Integers.swift.gyb#L789
>> there is
>> exactly the check that you’ve mentioned, but for all signed integers.
> Besides, it is very convenient to
>> have all the arithmetic operations be implemented the same way, even if
> there were no real overflows for division.
>
> I agree with this for the four basic operations, but not for the remainder
> operation.
>
> By definition, the remainder is always strictly smaller (in absolute value)
> than the divisor, so even if the division itself overflows, the remainder
> must be representable, so technically it never overflow.
>
> In the only actual case where the division overflow, that is Int.min / -1,
> the remainder is simply 0.
>
> For these reasons, I think it would make sense to explicitly request that
> the remainder operation never traps, and remove the overflow variants.
>
> Nicola
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution
On Fri, Jun 24, 2016 at 12:12 AM, Max Moiseev <moiseev@apple.com <mailto:moiseev@apple.com>> wrote:
Hi Nicola,
> For these reasons, I think it would make sense to explicitly request that
> the remainder operation never traps, and remove the overflow variants.
It will still trap when you divide by 0. But in that case falling back to the same generic overflow logic is not the best idea.
I agree that remainder is special, let me see what I can do about it.
Thanks,
Max
> On Jun 23, 2016, at 2:38 PM, Nicola Salmoria via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> Max Moiseev via swift-evolution <swift-evolution@...> writes:
>
>>> For FixedWidthInteger#dividedWithOverflow/remainderWithOverflow, under
> what situations would
>> you have an overflow? I could only come up with something like
> Int.min.dividedWithOverflow(-1).
>> If you look at the prototype here:
>>
> https://github.com/apple/swift/blob/master/test/Prototypes
> /Integers.swift.gyb#L789
>> there is
>> exactly the check that you’ve mentioned, but for all signed integers.
> Besides, it is very convenient to
>> have all the arithmetic operations be implemented the same way, even if
> there were no real overflows for division.
>
> I agree with this for the four basic operations, but not for the remainder
> operation.
>
> By definition, the remainder is always strictly smaller (in absolute value)
> than the divisor, so even if the division itself overflows, the remainder
> must be representable, so technically it never overflow.
>
> In the only actual case where the division overflow, that is Int.min / -1,
> the remainder is simply 0.
>
> For these reasons, I think it would make sense to explicitly request that
> the remainder operation never traps, and remove the overflow variants.
>
> Nicola
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution