-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: numerics reform #369
RFC: numerics reform #369
Conversation
Earlier drafts of this work were based on the listed alternative: more aggressive inlining of traits. iirc it was down to Float and Int, with SignedInt and UnsignedInt as potentials. FloatMath surviving is clearly motivated by the RFC, but what about the rest? Was it about deduplication and avoiding the more dubious methods like "abs on uints", or is this just a path of least resistance solution? I wasn't under the impression that we were particularly interested in supporting using a generic "Num". |
@gankro Thanks for bringing that up. I've revised the RFC with a new paragraph (see "Overview: the new hierarchy") to explain the motivation. I think flattening |
@gankro on further reflection, I've decided that the original plan (without |
👍 this strikes me as a moderate compromise between the two extremes. (I still think the signed/unsigned separation is a bit silly, but the majority seems to disagree) |
@aturon: Do you have any links where I can read about the ideas for replacing FromPrimitive and friends? |
@jsanders See this proposal and the discussion on this issue about |
Added these links to the RFC. |
Was having just Float, SignedInt, and UnsignedInt (and FloatMath as per discussion) ever evaluated? This is a denormalization that has more duplication, but avoids all the "this operation makes no sense" trouble. It also neatly matches what the primitive families actually are. |
@gankro Yes, I thought about that possibility. The updated RFC gives a (somewhat weak) justification for Also, while it's a bit far-fetched to imagine useful code that's generic over both ints and floats, being generic over signedness of ints is not so hard to imagine. (Note that the RFC does make some amount of generic programming over natural groupings of the primitive types an explicit goal.) |
Ah, I didn't process that only some of these would be part of the prelude. Okay, that makes sense. |
Are the numeric traits expected to be implemented outside of Currently My main concern is that signed integers have asymmetric range so generic functions over |
It's not an explicit design goal, but for custom-sized "primitive" types it would probably make sense.
The goal with I would welcome further input on the topic of what needs to go into the prelude. I worry that needing to import |
Maybe we should be evaluating a way to mark a trait as |
fn is_infinite(self) -> bool; | ||
fn is_finite(self) -> bool; | ||
fn is_normal(self) -> bool; | ||
fn classify(self) -> FPCategory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we rename FPCategory
to FloatCategory
?
Thanks a bunch for drawing up best proposal for Rust numerics yet! |
cc. @sebcrozet @SiegeLord |
So in the docs should we be specific about what types should implement these traits? For example, I am guessing they would not be implemented by big integers and floats...? |
I have some code that relies only on field operations (Add + Sub + Mul + Div + Zero + One + Clone), and also a type to represent finite-field arithmetic (GF(2^64)) that Rem and the bitwise operations do not make sense. What should be done if this RFC is to be merged? Since it seems Zero and One are going away? |
@kennytm Nothing prevents you from writing these traits in your own library, which I believe is the overall intent of this RFC: Make algebraic hierarchies a problem for the community to work out in the cargo ecosystem. |
I am thinking it might be wise to start a numeric lib with things like the additive and multiplicative identities and such. Then folks have a place to turn once we kill some of these numeric traits. I began num-rs quite some time ago... maybe there is something we can salvage from there? |
fn exp2(self) -> Self; | ||
fn ln(self) -> Self; | ||
fn log2(self) -> Self; | ||
fn log10(self) -> Self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of these have worried me in the past in the sense that although they are LLVM intrinsics, they're often lowered to function calls at compile-time into libraries like libm
. By providing these functions in libcore we're semi-stating that they're available for everyone forever (some of them do have x86 instructions, for example), but we're not necessarily delivering on that statement.
A small wory, just wanted to point out why these are singled out for being in libcore rather than libstd. Anyone using these functions and libcore directly will likely already know how to get them anyway
I am sorry for the late response. I’m only dealing with this now because the changes broke a project of mine. I understand the rationale behind the separation of |
@ruud-v-a Thanks for the feedback! We're actually considering making |
This commit adds stability markers for the APIs that have recently been aligned with [numerics reform](rust-lang/rfcs#369). For APIs that were changed as part of that reform, `#[unstable]` is used to reflect the recency, but the APIs will become `#[stable]` in a follow-up pass. In addition, a few aspects of the APIs not explicitly covered by the RFC are marked here -- in particular, constants for floats. This commit does not mark the `uint` or `int` modules as `#[stable]`, given the ongoing debate out the names and roles of these types. Due to some deprecation (see the RFC for details), this is a: [breaking-change]
…ichton This commit adds stability markers for the APIs that have recently been aligned with [numerics reform](rust-lang/rfcs#369). For APIs that were changed as part of that reform, `#[unstable]` is used to reflect the recency, but the APIs will become `#[stable]` in a follow-up pass. In addition, a few aspects of the APIs not explicitly covered by the RFC are marked here -- in particular, constants for floats. This commit does not mark the `uint` or `int` modules as `#[stable]`, given the ongoing debate out the names and roles of these types. Due to some deprecation (see the RFC for details), this is a: [breaking-change] r? @alexcrichton cc @bjz
The only code associated with this comment are the traits below: pub trait RotateLeft<RHS> {
type Output;
fn rotate_left(self, rhs: RHS) -> Self::Output;
}
pub trait RotateRight<RHS> {
type Output;
fn rotate_right(self, rhs: RHS) -> Self::Output;
}
pub trait SwapBytes<RHS> {
fn swap_bytes(self) -> Self;
fn from_be(x: Self) -> Self;
fn from_le(x: Self) -> Self;
fn to_be(self) -> Self;
fn to_le(self) -> Self;
} I would like to bring attention to the particular use case of using these subsets of the current A second reason why these method subsets are useful to separate from the
After some experimentation, it seems that A side note (and perhaps outside the scope of this comment) is that In conclusion, there are at least 2 compelling reasons (the |
This implements a considerable portion of rust-lang/rfcs#369 (tracked in #18640). Some interpretations had to be made in order to get this to work. The breaking changes are listed below: [breaking-change] - `core::num::{Num, Unsigned, Primitive}` have been deprecated and their re-exports removed from the `{std, core}::prelude`. - `core::num::{Zero, One, Bounded}` have been deprecated. Use the static methods on `core::num::{Float, Int}` instead. There is no equivalent to `Zero::is_zero`. Use `(==)` with `{Float, Int}::zero` instead. - `Signed::abs_sub` has been moved to `std::num::FloatMath`, and is no longer implemented for signed integers. - `core::num::Signed` has been removed, and its methods have been moved to `core::num::Float` and a new trait, `core::num::SignedInt`. The methods now take the `self` parameter by value. - `core::num::{Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}` have been removed, and their methods moved to `core::num::Int`. Their parameters are now taken by value. This means that - `std::time::Duration` no longer implements `core::num::{Zero, CheckedAdd, CheckedSub}` instead defining the required methods non-polymorphically. - `core::num::{zero, one, abs, signum}` have been deprecated. Use their respective methods instead. - The `core::num::{next_power_of_two, is_power_of_two, checked_next_power_of_two}` functions have been deprecated in favor of methods defined a new trait, `core::num::UnsignedInt` - `core::iter::{AdditiveIterator, MultiplicativeIterator}` are now only implemented for the built-in numeric types. - `core::iter::{range, range_inclusive, range_step, range_step_inclusive}` now require `core::num::Int` to be implemented for the type they a re parametrized over.
This implements a considerable portion of rust-lang/rfcs#369 (tracked in #18640). Some interpretations had to be made in order to get this to work. The breaking changes are listed below: [breaking-change] - `core::num::{Num, Unsigned, Primitive}` have been deprecated and their re-exports removed from the `{std, core}::prelude`. - `core::num::{Zero, One, Bounded}` have been deprecated. Use the static methods on `core::num::{Float, Int}` instead. There is no equivalent to `Zero::is_zero`. Use `(==)` with `{Float, Int}::zero` instead. - `Signed::abs_sub` has been moved to `std::num::FloatMath`, and is no longer implemented for signed integers. - `core::num::Signed` has been removed, and its methods have been moved to `core::num::Float` and a new trait, `core::num::SignedInt`. The methods now take the `self` parameter by value. - `core::num::{Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}` have been removed, and their methods moved to `core::num::Int`. Their parameters are now taken by value. This means that - `std::time::Duration` no longer implements `core::num::{Zero, CheckedAdd, CheckedSub}` instead defining the required methods non-polymorphically. - `core::num::{zero, one, abs, signum}` have been deprecated. Use their respective methods instead. - The `core::num::{next_power_of_two, is_power_of_two, checked_next_power_of_two}` functions have been deprecated in favor of methods defined a new trait, `core::num::UnsignedInt` - `core::iter::{AdditiveIterator, MultiplicativeIterator}` are now only implemented for the built-in numeric types. - `core::iter::{range, range_inclusive, range_step, range_step_inclusive}` now require `core::num::Int` to be implemented for the type they a re parametrized over.
…erability Deprecate Computed Overridability and `.readOnly()`
This RFC is preparation for API stabilization for the
std::num
module. The goal is to finish the simplification efforts started in @bjz's reversal of the numerics hierarcy.Broadly, the proposal is to collapse the remaining numeric hierarchy in
std::num
, and to provide only limited support for generic programming (roughly, only over primitive numeric types that vary based on size). Traits giving detailed numeric hierarchy can and should be provided separately through the Cargo ecosystem.Thus, this RFC proposes to flatten or remove most of the traits currently provided by
std::num
, and generally to simplify the module as much as possible in preparation for API stabilization.Rendered