Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
Behaviour of div / mod on Non-Ints #5388
Current implementation of `mod` has (Real, Real) signature and uses `div (Int,Int)` to perform the division. This creates an LTA error that mentions `div` when argumenemts aren't Ints:
<Zoffix> m: say 2 mod 1.5
Reading the spec (http://design.perl6.org/S03.html), descriptions of infix:<mod>/infix:<div> suggest they should work on all numeric types, as long as LHS/RHS are the same type:
-------------quote from spec----------------------
infix:<div>, integer division
$numerator div $denominator
Dispatches to the infix:<div> multi most appropriate to the operand types, returning a value of the same type. Not coercive, so fails on differing types.
Policy on what to do about division by zero is up to the type, but for the sake of hyperoperators and junctions those types that can represent overflow (or that can contain an unthrown exception) should try to do so rather than simply throwing an exception. (And in general, other operators that might fail should also consider their use in hyperops and junctions, and whether they can profitably benefit from a lazy exception model.)
On the other hand, div wants to be very efficient and jittable when used as a low-level operation, so when you use div on two native ints, it relies on hardware to detect division by 0. Hence, it will always throw an exception rather than return a Failure.
In general, div should give the same result as
$x div $y == floor($x/$y)
but the return value should be the same type as $x.
This identity stops holding when $x/$y degrades to a Num and runs into precision limits. A div operation on two Int objects must always be done precisely.
$x mod $y
Dispatches to the infix:<mod> multi most appropriate to the operand types, returning a value of the same type. Not coercive, so fails on differing types.
This should preserve the identity
$x mod $y == $x - ($x div $y) * $y
I've used a bad example in the OP.
The issue is mod/div only work on Int types and the spec specs all numerics, even though the method is non-coercive:
On 06/18/2016 12:39 AM, Zoffix Znet (via RT) wrote:
But that's not what your example uses. It's Int mod Rat, so it
: Not coercive, so fails on differing types.
So I don't see the bug yet.
On Wed, 27 Jul 2016 17:43:39 -0700, moritz wrote:
Right, I've copy-pasted the wrong example. Different types aren't the issue. The Int-only impl is the issue:
m: say 2.5 mod 2.5
The spec suggests that should work.