9

I previously incorrectly thought that the % operator returned the remainder and the mod operator returned the modulus (the remainder and modulus are the same when the operands are both positive or both negative but differ when one operand is positive and the other is negative. Compare Raket's remainder and modulo functions).

However, that's not correct at all – both % and mod return the modulus; neither return the remainder. In fact, it looks like mod will always return exactly the same value as % would have, if called with the same arguments. As far as I can tell, the only difference is that % can be called with non-integer arguments, whereas mod throws an exception if called with anything other than Int:D or int.

So, what's the point of mod? Is there some performance gain from using it (maybe by saving the optimizer some specialization work?) or is there some other difference I'm missing?

codesections
  • 8,900
  • 16
  • 50
  • 2
    Any info to be gleaned from [speculifcations](https://design.raku.org)? – Elizabeth Mattijsen Feb 10 '22 at 15:21
  • 1
    @ElizabethMattijsen not particularly. S03 describes both [`%`](https://design.raku.org/S03.html#line_826) and [`mod`](https://design.raku.org/S03.html#line_855) but doesn't provide any details about why `mod` is useful. Worth checking, though! – codesections Feb 10 '22 at 15:27

2 Answers2

6

TL;DR My takeaway from a quick skim of sources is that % is (supposed to be) the rational or generic modulus op, whereas mod is a dedicated integer modulus op. For some inputs they yield the same result.

The rest of this answer just references the sources I looked at.

Doc

mod:

Integer modulo operator. Returns the remainder of an integer modulo operation.

%:

Modulo operator. Coerces to Numeric first.

Generally the following identity holds:

my ($x, $y) = 1,2;
$x % $y == $x - floor($x / $y) * $y

roast

Search of roast for modulus lists just S03-operators/arith.t. Leads to:

S03

infix:<%>, modulo

coerces ... then calculates the remainder ... defined as:

$x % $y == $x - floor($x / $y) * $y

If both operands are of integer or rational type, the operator returns the corresponding Rat value (except when the result does not fit into a Rat, as detailed in S02).

infix:<mod>, integer modulo

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

IRC

Search of #perl6 for mod integer.

Rakudo source code

raiph
  • 31,607
  • 3
  • 62
  • 111
  • 1
    "If both operands are of integer or rational type, the operator returns the corresponding Rat value" Hmmm, this is *not* how `%` currently behaves – it currently returns an `Int` (/ `int`) when called with two `Int`s (/ two `int`s). So the only difference left from S03 is that `%` tries to coerce and handles non-`Int`s whereas `mod` throws an error. And I don't see when that behavior would be useful (unless it's for the perf reasons I speculated about in the Q). – codesections Feb 11 '22 at 00:40
  • "not how `%` currently behaves ... only difference left from S03 is that `%` tries to coerce and handles non-`Int`s." Afawct, there's just those 2 differences, right? So my guess is it's half done and @Larry would want it completed. "I don't see when that behavior would be useful". I don't, but one can safely presume that @Larry (which refers to the entire PL design team) didn't specify/speculate a difference without very good reason, given that that was their standard for all things. Sometimes stuff didn't get finished because it was controversial, sometimes lack of tuits. I'll research that. – raiph Feb 11 '22 at 08:08
2

The 'bible' of IEEE P754 says this...

Floating point remainder. This is not like a normal modulo operation, it can be negative for two positive numbers. It returns the exact value of x–(round(x/y)·y).

librasteve
  • 6,832
  • 8
  • 30
  • I'm confused: my StackOverflow inbox claims I got an answer starting with `afaict the general idea is that mod is for exact things (Int, Rat) whereas % is for inexact things`, and links to this answer. But the full text of this answer is currently "012345678901234567890123456789 > 30 chars\n\n per [P754][1]\n\n [1]: https://stackoverflow.com/questions/158120/math-ieeeremainder-returns-negative-results-why". And this answer shows that it's never been edited. ??? – codesections Feb 13 '22 at 20:54
  • sorry @codesections ... i was in dive/edit mode – librasteve Feb 13 '22 at 20:58