-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Begin stripping down core::num #18827
Conversation
Note, I am still running some tests locally, there might be some breakages - I will rebase in a bit. Apologies for the size of this. cc. @aturon |
The standard library can't just reserve all of these useful method names in the prelude without a plan for support of big integers, decimals and arbitrary precision floats. It would no longer be possible to write a generic number library with sane method names. |
@thestinger We have removed the traits from the prelude in the interests of future extensibility. |
08bbdda
to
b059fb3
Compare
The |
@bjz: It shouldn't be done via traits if it's not meant to be used for generic programming. |
Re. |
I can't see how intentionally poor library design makes sense regardless of what's in the prelude. If doing it properly is considered too verbose, then that's a language problem. In C++, it's possible to write code using references and values based on the semantics required for all types without adding any verbosity for primitive types. I think fixing a serious regression from C++ should have been considered as an alternative to crippling support for non-primitive number types. |
b059fb3
to
357ba13
Compare
@thestinger Objecting to the design of the language is off-topic for this PR. Please file an RFC if you have any concrete changes to the trait system that you would like to make. |
357ba13
to
e271f3e
Compare
e271f3e
to
22ae9d0
Compare
r? @aturon |
@bjz Thanks so much for doing this (and so quickly)! I'll review it shortly. |
22ae9d0
to
5fe8ca0
Compare
@bjz This is really nice work! I left a few minor comments, but overall this is looking good to me. I would be fine with dropping One other thing I'm uneasy about is the change to |
I would vote for dropping them. With UFCS and your proposed operator cleanup you should be able to do something like |
@gankro good point! |
Also if signed is leaving the prelude, do we even need it? I thought its whole justification in the RFC was to provide some prelude functionality? |
@pcwalton: I don't see how it's off-topic. I'm pointing out that this is a major regression for types like big integers and that alternatives were not considered. I haven't proposed any changes to the trait system. |
It also serves to cut down a bit of duplication between the int and float traits. You could instead have the methods separately on |
I still favour either the denormalization of
or
As this seems like a more natural grouping. The method duplication argument doesn't seem very convincing for a bunch of extension traits that will never be simultaneously impl'd by one type. It's fairly minor maintenance to have the same methods on two traits. |
These traits include many methods that are not useful outside of generic code. For example, there are a large number of methods returning constants without a use case outside of generics. The ability to write code that's generic over number types is clearly useful, and there are even cases in the standard library. It's currently possible to use types like big integers with The existing good practice in traits and generics is to take For example, searching for an integer key in a map type looks like Especially with traits like |
@thestinger A meta-point: Your objections were specific to the prelude and were raised 5-6 days after the RFC was accepted. Procedural objections aren't going to work this time.
Yes, they were. Big integers were specifically called out as being out of scope of the Rust standard library's trait hierarchy. Your objections were specific to the prelude and covered by the fact that these traits are not in it.
Nobody said anything about |
There are often unforeseen consequences to a proposal, as pointed out in the pull request itself: "Some interpretations had to be made in order to get this to work.". The fact that I'm raising concerns here doesn't make those concerns any more or less valid. As the author of rust-gmp and one of the people who was involved in previous number design discussions, it should not be a surprise that I have an opinion about it. I need watch the pull request queue, because many major changes do not go through the RFC process. I don't have the time to read through every proposal too, especially since only a fraction are accepted.
The
I'm stating that a different implementation of |
There are plenty of issues in my comment that were not brought up in the RFC and there is no mention of the prelude here:
No one brought up these issues on the RFC or mentioned various alternatives at both the language and library level without the same negative consequences. That's what happens when the discussion only involves the people with one perspective on the issue. |
That's true. You can't point to procedural issues this time, however; the RFC process took place, you did not take part in it, and now you're raising objections on the PR while simultaneously unfairly implying that there is a problem with the RFC process.
I was referring to your comments in the RFC.
To me that was clearly just a mistake with the RFC, otherwise @aturon's reply would have not made sense.
This is what I mean by bringing up procedural issues. By your own admission, you didn't "have time to" to take part in the RFC. So you can't bring up procedural issues if you didn't bother to get involved. We followed the procedure to the letter.
I don't understand this. Big integers and primitives do have to have different implementations of |
Fix rust-lang/rust#18827 related issues.
Fix rust-lang/rust#18827 related issue.
What is the solution here for code that needs to abstract over both integers and floats? Even defining your own impl<T: Int> Num for T { /* ... */ }
impl<T: Float> Num for T { /* ... */ } I don't see any way of working around this problem except for copious use of macros to stamp out implementations, which kind of defeats the purpose of having compile-time polymorphism. |
One solution might be to resurrect https://github.com/bjz/num-rs/ |
@yuriks The intersection of We did consider having a |
I'm currently working on getting num-rs back up to scratch :) |
@bjz Delighted to hear it! |
It was removed from the prelude as part of <rust-lang/rust#18827>.
It was removed from the prelude as part of <rust-lang/rust#18827>.
It was removed from the prelude as part of <rust-lang/rust#18827>.
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 oncore::num::{Float, Int}
instead. There is no equivalent toZero::is_zero
. Use(==)
with{Float, Int}::zero
instead.Signed::abs_sub
has been moved tostd::num::FloatMath
, and is no longer implemented for signed integers.core::num::Signed
has been removed, and its methods have been moved tocore::num::Float
and a new trait,core::num::SignedInt
. The methods now take theself
parameter by value.core::num::{Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}
have been removed, and their methods moved tocore::num::Int
. Their parameters are now taken by value. This means thatstd::time::Duration
no longer implementscore::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.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 requirecore::num::Int
to be implemented for the type they a re parametrized over.