-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Restrict std::num::{Zero, One} implementors and improve std::num::pow implementation #11664
Conversation
I'm not keen on removing |
I'm not sure I agree with the I think we should keep it for now. Besides being convenient, it also removes the need of having |
Ok, all those reasons seem pretty valid. Should we add a |
Maybe; but zero seems more fundamental, e.g. it's the base case of Euclid's algorithm, and exponentiation-by-squaring, etc etc. |
Aren't all identities fundamental thingies though? |
I don't think |
Rebased, rolling back the removal of |
Rebased - removed some gunk hanging around from the rollback. |
small nit, otherwise LGTM |
else { | ||
let mut acc: T = one(); | ||
let mut base = base; | ||
let mut exp = exp; |
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.
Both this and base
can be mutable via mut base: T
and mut exp: uint
in the function definition.
Also, personally, I'd rather see if exp % 2 == 1
and exp /= 2
and just let the optimiser handle lowering it to optimised form.
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.
Not sure if the optimizer will optimize it down to exp & 1 == 1
, though. I recently proposed a patch to change this in the is_even
implementation of some types.
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.
It does. This is bread-and-butter peep-hole optimisation stuff. i.e. it actually gets "optimised" to have no modulus call even without any optimisations on, e.g.
#[crate_type="lib"];
#[no_mangle]
pub fn parity(n: uint) -> bool {
n % 2 == 1
}
Then compiling with rustc -S modulo.rs
(no optimisations) and trimming out the relevant section of parity
, gives:
andq $1, %rax # a bitwise and!
cmpq $1, %rax
sete %cl
(There's a pile of other junk from the possibility of %
failing if the RHS is zero (this code path is removed with optimisation), and because of our poor handling of booleans.)
I'd prefer squashing these 2 commits into the other 2 if possible. No need to have them separate. The rest LGTM |
@flaper87 Ok, squashed. Shame to see the comment history go, but no matter. More important is a clean git history! |
LGTM, thanks a lot! @huonw r? |
/// | ||
/// ~~~ | ||
/// a + 0 = x ∀ a ∈ Self | ||
/// 0 + a = x ∀ a ∈ 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.
Should these two laws have = a
instead of = x
?
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.
Good catch!
r=me with typo fix. |
Nice job on all this! |
…their appropriate use Zero and One have precise definitions in mathematics. Documentation has been added to describe the appropriate uses for these traits and the laws that they should satisfy. For more information regarding these identities, see the following wikipedia pages: - http://wikipedia.org/wiki/Additive_identity - http://wikipedia.org/wiki/Multiplicative_identity
The implementation has been made more succinct and no longer requires Clone. The coverage of the associated unit test has also been increased to check more combinations of bases, exponents, and expected results.
@alexcrichton Rebased and did an r=you. Hopefully that's ok. |
`Zero` and `One` have precise definitions in mathematics as the identities of the `Add` and `Mul` operations respectively. As such, types that implement these identities are now also required to implement their respective operator traits. This should reduce their misuse whilst still enabling them to be used in generalized algebraic structures (not just numbers). Existing usages of `#[deriving(Zero)]` in client code could break under these new rules, but this is probably a sign that they should have been using something like `#[deriving(Default)]` in the first place. For more information regarding the mathematical definitions of the additive and multiplicative identities, see the following Wikipedia articles: - http://wikipedia.org/wiki/Additive_identity - http://wikipedia.org/wiki/Multiplicative_identity Note that for floating point numbers the laws specified in the doc comments of `Zero::zero` and `One::one` may not always hold. This is true however for many other traits currently implemented by floating point numbers. What traits floating point numbers should and should not implement is an open question that is beyond the scope of this pull request. The implementation of `std::num::pow` has been made more succinct and no longer requires `Clone`. The coverage of the associated unit test has also been increased to test for more combinations of bases, exponents, and expected results.
Fix/11134 Fix rust-lang#11134 Hir of `qpath` will be `TypeRelative(Ty { kind: Path(LangItem...` when a closure contains macro (e.g. rust-lang/rust-clippy#11651) and rust-lang#11134, it causes panic. This PR avoids panicking and emitting incomplete path string when `qpath` contains `LangItem`. changelog: none
Zero
andOne
have precise definitions in mathematics as the identities of theAdd
andMul
operations respectively. As such, types that implement these identities are now also required to implement their respective operator traits. This should reduce their misuse whilst still enabling them to be used in generalized algebraic structures (not just numbers). Existing usages of#[deriving(Zero)]
in client code could break under these new rules, but this is probably a sign that they should have been using something like#[deriving(Default)]
in the first place.For more information regarding the mathematical definitions of the additive and multiplicative identities, see the following Wikipedia articles:
Note that for floating point numbers the laws specified in the doc comments of
Zero::zero
andOne::one
may not always hold. This is true however for many other traits currently implemented by floating point numbers. What traits floating point numbers should and should not implement is an open question that is beyond the scope of this pull request.The implementation of
std::num::pow
has been made more succinct and no longer requiresClone
. The coverage of the associated unit test has also been increased to test for more combinations of bases, exponents, and expected results.