Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upEuclidean modulo #2169
Conversation
varkor
added some commits
Oct 9, 2017
scottmcm
added
the
T-libs
label
Oct 10, 2017
This comment has been minimized.
This comment has been minimized.
mcarton
commented
Oct 10, 2017
•
|
While I like the proposal, I really don't like the |
This comment has been minimized.
This comment has been minimized.
|
@mcarton What part of it? That it has a short suffix, or that it has a suffix and not a prefix? Both? |
This comment has been minimized.
This comment has been minimized.
|
How common is usage of these operations? Would it warrant adding another operator to the language? |
This comment has been minimized.
This comment has been minimized.
|
@Centril: I couldn't think of a good way to measure the use of these operations, as they can be implemented in various different ways. The rationale behind advocating new methods, rather than new operators, was that we could see how often they were used in Rust (say, 12 months down the line), to see whether they were used common enough to be worth considering as operators. |
This comment has been minimized.
This comment has been minimized.
|
@varkor this makes sense to me. However, many users will shy away from functionality until it has been stabilized, thus usage metrics for unstable stuff might not be fully representative. |
This comment has been minimized.
This comment has been minimized.
mcarton
commented
Oct 11, 2017
The shortness. |
This comment has been minimized.
This comment has been minimized.
|
If the output of these are always positive, should they return unsigned types instead? Similarly, it feels like something here should enable |
This comment has been minimized.
This comment has been minimized.
|
@scottmcm: I followed the precedent set by the Regarding inter-type modulo, the |
This comment has been minimized.
This comment has been minimized.
|
As someone who has hacked euclidean modulo as |
This comment has been minimized.
This comment has been minimized.
|
Alternative name possibilities?
|
This comment has been minimized.
This comment has been minimized.
tspiteri
commented
Oct 18, 2017
|
Maybe |
kennytm
reviewed
Oct 18, 2017
| // Comparison of the behaviour of Rust's truncating division | ||
| // and remainder, vs Euclidean division & modulo. | ||
| (-8 / 3, -8 % 3) // (-2, -2) | ||
| (-8.div_e(3), -8.mod_e(3)) // (-3, 1) |
This comment has been minimized.
This comment has been minimized.
kennytm
Oct 18, 2017
Member
. has higher precedence than unary minus. This will be evaluated as -( 8.mod_e(3) ) i.e. -2. You want (-8).mod_e(3).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@est31: I ran some benchmarks before making the RFC comparing the implementation for Euclidean modulo as suggested in the RFC with the branchless variant, and the RFC version turned out to be ~5x faster. It could be that the branch prediction is making the benchmarks nonrepresentative, so if you have any results to the contrary, please do share them! @tspiteri: Flooring division and modulo is subtly different (see this paper for more details — essentially Euclidean modulo always returns a nonnegative value), so avoiding the terminology |
This comment has been minimized.
This comment has been minimized.
|
Regarding the name: I'm happy with a change of name, provided it doesn't become cumbersome — I'd personally prefer the operation name to come first for aiding discoverability (for example, if other methods of rounding are added in the future) via autocomplete, etc. Perhaps |
This comment has been minimized.
This comment has been minimized.
|
@varkor I haven't run any benchmarks and was just guessing that a branchless version is faster. The code path is definitely not hot so I didn't care much. |
This comment has been minimized.
This comment has been minimized.
tspiteri
commented
Oct 18, 2017
|
@varkor Yes, flooring and Euclidean division are different; to use |
This comment has been minimized.
This comment has been minimized.
tspiteri
commented
Oct 18, 2017
|
@est31 Your version can overflow. |
This comment has been minimized.
This comment has been minimized.
fanzier
commented
Oct 18, 2017
|
@tspiteri I agree that it makes sense to consider what other languages do but it shouldn't be the only argument -- Rust does a lot of things better/differently than other languages. I don't see how differences to other software would be a disadvantage for Rust's modulo function, given that the modulo operator You can also view the bandwagon argument from the opposite side: In mathematics, Euclidean modulo is standard that everyone uses, presumably because it has the most regular properties. I also don't think the arguments in the paper are a matter of taste: the code examples really are more uniform if Euclidean division is used. That is anecdotal evidence but I don't think we have any better kind of evidence. That said, I don't care very much whether it's flooring or Euclidean modulo. I just think the discussion should include more than personal preference and the bandwagon argument. (Also, I'm kind of afraid this proposal will die because of bikeshedding about this.) |
This comment has been minimized.
This comment has been minimized.
Can you elaborate on usage of negative-divisor modulo in mathematics? I'm only familiar with strictly-positive ones, and for that flooring and euclidean are the same. |
This comment has been minimized.
This comment has been minimized.
fstirlitz
commented
Oct 19, 2017
|
Rambling a bit here: Parroting mathematical usage can just as well be considered 'the bandwagon argument': π is the standard that everyone uses, mostly for the sake of tradition, even though τ has better mathematical properties. Euclidean division is defined the way it is because it aligns well with Euclid's division theorem for integers (which requires the remainder to satisfy 0 ≤ r < |d|). This theorem in turn is formulated this way presumably because this is the most concise way to make the division result unique. But this property cannot be maintained in general Euclidean domains (the 'proper' structure to study division-with-remainder), where a total order relation may fail to exist, nor there may be any way to make the result 'naturally' unique (Gaussian integers, polynomials). From this more general perspective, floor division is just as good a definition of division-with-remainder as the 'Euclidean' division. I see no properly mathematical reason to prefer one over the other. And I don't recall any programming problem where a division-with-remainder by a negative divisor is meaningful, so from this point of view, there also seems to be no reason to prefer either. (Well, I think I can imagine a problem where the choice of definition may conceivably matter, but I still don't see how either is more advantageous). That perspective, however, would suggest also adding a ceiling division operator (it's the answer to the question 'how many buckets of capacity n do you need to contain N items?') and a combined division-modulo operation (which answers the problem 'given a scalar offset into a two-dimensional array, what are its corresponding two-dimensional cordinates?'). Admittedly the former can be expressed with |
This comment has been minimized.
This comment has been minimized.
tmccombs
commented
Oct 21, 2017
|
+1 for a combined division-modulo operation. |
varkor
added some commits
Oct 23, 2017
This comment has been minimized.
This comment has been minimized.
|
I've updated the method names in the proposal with a more descriptive Additionally, I've extended the RFC slightly to include Euclidean division and modulo methods for Regarding the discussion about flooring versus Euclidean division/modulo that arose: I think @fstirlitz summed it up well; in practice, there will very rarely be a difference between the results of flooring and Euclidean modulo/division — taking the negative modulo of a number is a very uncommon operation: it's just a matter of deciding what the behaviour in this particular edge case should be. My feeling was, and the general feeling on the internals thread seemed to be, that Euclidean modulo was the least surprising of the two (and mathematical consistency is a bonus). I'd be hesitant to add a combined division-modulo method in this RFC — it seems like a separate, though tangentially related, issue — and it'd be better not to crowd this RFC with new methods. |
This comment has been minimized.
This comment has been minimized.
|
Regarding @scottmcm's point about the use cases, I am starting to feel persuaded. Indexing using the result is common, and it would be nice to avoid casts everywhere. Once/if implicit widening ever happens, the distinction should be minimal too. However, I would prefer to keep the arguments signed — making the second parameter unsigned, though removing the distinction between flooring vs Euclidean modulo, does make it more awkward for the user — as on top of
|
This comment has been minimized.
This comment has been minimized.
|
I'm not really sure whether we want long names like |
This comment has been minimized.
This comment has been minimized.
|
Following on from @est31's point: I don't see the advantage to spelling the name I'd like to know what other people think about changing the return type before making any changes, though. It'd be really nice to finalise this RFC at last. |
This comment has been minimized.
This comment has been minimized.
tspiteri
commented
Feb 13, 2018
•
|
About the return type, it depends on whether this is meant to look like the other arithmetic operators, or like other inherent functions. For operators on primitives I would expect the output to be like |
This comment has been minimized.
This comment has been minimized.
tspiteri
commented
Feb 13, 2018
|
And another thing, returning unsigned values suggests to me that this is only intended for indexing, not as a normal division operation where operating on signed integers should return a signed integer. But in that case it would make more sense to call it something like |
This comment has been minimized.
This comment has been minimized.
|
@tspiteri makes a good point. I think that considering It's unfortunate that the signature will mean casting is required in some cases, but the consistency seems more important here. |
This comment has been minimized.
This comment has been minimized.
|
@sfackler: is it possible to follow up regarding the naming convention — taking into account the points others have made, is there strong motivation for requiring After that has been resolved, are there any other issues stalling this RFC from a FCP? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Feb 27, 2018
•
|
Team member @sfackler has proposed to merge this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Feb 28, 2018
|
|
rfcbot
removed
the
proposed-final-comment-period
label
Feb 28, 2018
This comment has been minimized.
This comment has been minimized.
But it's also adding new methods, so maybe that just means the set of added methods isn't sufficient yet. Conveniently, there's even naming and semantic precedent for it in You can have (Their types being |
This comment has been minimized.
This comment has been minimized.
This signature (and similarly if On the other hand, the current signature is very amenable to modification in the future when implicit widening is introduced, which should eliminate the problems entirely. (Additionally, for consistency purposes, such a signature for |
This comment has been minimized.
This comment has been minimized.
|
Regarding |
This comment has been minimized.
This comment has been minimized.
|
Hold up, why is rfcbot only listing four members of the libs team? The libs team has eight people on it. |
This comment has been minimized.
This comment has been minimized.
|
We subdivided the libs team a bit. |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Mar 10, 2018
|
The final comment period is now complete. |
alexcrichton
referenced this pull request
Mar 15, 2018
Open
Tracking issue for RFC 2169: Euclidean Modulo #49048
This comment has been minimized.
This comment has been minimized.
|
Alright! FCP has now elapsed and it looks like there were no major things brought up, so I'm going to merge! |
alexcrichton
merged commit dfad2c9
into
rust-lang:master
Mar 15, 2018
varkor
deleted the
varkor:euclidean-modulo
branch
Mar 15, 2018
This comment has been minimized.
This comment has been minimized.
|
Updated Rendered link + added tracking issue to top post. |
varkor commentedOct 9, 2017
•
edited by Centril
Proposal to add Euclidean modulo & division functionality for integers and floating-point numbers, to address common issues with taking remainders involving negative numbers.
Internals discussion here.
Rendered.
Tracking issue.