Looking at compiler/builtins/docs/Num.roc:784-805
, //
is documented as desugaring to Num.divRound
(which isn't actually defined/implemented). In TUTORIAL.md:1944
, and roc-for-elm-programmers.md:1297
, it's defined as desugaring to Num.divFloor
.
The present behavior is clearly divTrunc(ate), which doesn't appear to have an corresponding, precisely-named function. We had internal references to a "NUM_DIV_INT" which was accurate but perhaps whose naming is too circular ("integer division has the behavior that integer division has"). I had mistakenly conflated flooring division with truncating division in https://github.com/rtfeldman/roc/pull/2840.
» 23 // 13
1 : Int *
» -23 // 11
-2 : Int *
» 23 // -11
-2 : Int *
If the behavior were Num.divRound
, we'd expect 23 // 13 == 2
, and if it were Num.divFloor
(at least, iiuc, following the mathematical meaning of floor, i.e. "towards negative infinity"), we'd expect -23 // 11 == -3
.
I'm assuming C as well as the integer signed division operation in most modern hardware "truncates towards zero," thus is the behavior most programmers would expect across the broadest swath of languages.
Further, I suspect most programmers share in my weakness of not being great at internalizing edge cases involving negative numbers. We may think of a flooring operation as "going towards zero" since that's what it does for positive results (even though more precisely we'd call it a "truncating" operation); likewise we might incorrectly/casually think of a ceiling operation as "going away from zero." Mathematically, ceiling should be going towards positive infinity, again, iiuc.
» Num.divCeil -5 2
-2 : Int *
» Num.divFloor -5 2
-2 : Int *
In any case, these should never produce the same answer when there's a non-zero remainder.
I propose the following:
Num.divFloor
is renamed to Num.divTruncate
(since that's the behavior it implements already).//
is redefined as desugaring to Num.divTruncate
.Num.divRound
.Num.divFloor
(Num.divCeil
is correct but actually no longer has a paired opposite-rounding variant).Num.divRoundAwayFromZero
(a more succinct yet equally precise name to be determined). If we decide we want it, that may suggest the name of Num.divTruncate
should actually be something like Num.divRoundTowardsZero
.I agree that the default should be that integer division goes towards zero, which would match what c++ does and most other languages. It also is likely easier to reason about for most people.
I think that if we have a divCeil
we should also have a divFloor
. I think that these should go towards positive and negative infinity respectively. Otherwise, I think the naming would be very confusing because they wouldn't match what ceil
and floor
normally do.
I think that divTruncate
is an ok name. Though maybe we want to to be part of the group of rounding specific functions something like divRoundIn
, divRoundOut
, divRound
. Of course those aren't great names, but divRoundUp
and divRoundDown
are ambiguous so in and out are my best thoughts so far if we want explicit rounding options.
ooh, I like divRoundIn
. Very concise and technically unambiguous (if the implied relative anchor is correctly inferred by the reader, that is).
Up, Down, In, and Out, taken together, sounds a bit like subatomic particle (quark) naming (https://global.jaxa.jp/article/interview/vol43/img/photo_04_e.gif)... probably not something we want to replicate.
So we want divRoundStrange
and divRoundCharm
? I think that would be a good feature to have only enabled on april fools day.
And leap day.
good catch @Kevin Gillette!
I agree, we should rename the current divFloor
to divTrunc
:thumbs_up:
also should probably get rid of divRound
and divFloor
in the docs, and consider re-adding them later if there's demand
Richard Feldman said:
I agree, we should rename the current
divFloor
todivTrunc
:thumbs_up:
Sounds good. I'll do that as part of the non-div aspects of https://github.com/rtfeldman/roc/issues/2826, which I should be able to wrap up soon (the issue isn't actually properly complete yet, as only the "div" changes are merged).
https://github.com/rtfeldman/roc/pull/2883 should be ready.
Last updated: Jul 06 2025 at 12:14 UTC