No Add Sub Mul Div for primative types
What is the reasoning behind not having add sub mul div implementations on Rational for primitive types?
If you want to do an operation like that, you can convert the primitive value to a Rational. Converting a primitive integer to a Rational using Rational::from is very cheap; if the integer's absolute value is less than 2^64, there is no memory allocation involved.
Malachite is already very large, and having implementations for every possible combination of types would make it even larger. For consistency, I'd need to also create implementations for operations between Naturals and primitive types, Integers and primitive types, Naturals and Integers, Naturals and Rationals, and Integers and Rationals. Malachite will have more numeric types in the future, and the number of combinations of types will go up quadratically.
However, Malachite does provide implementations of PartialEq and PartialOrd for all combinations of types, as a sort of compromise.
The use case on including primitive types is less about variables (where your argument about then wishing to support the factorial combination of all your own types makes sense) and more about literals.
For example, the maximum value that can fit in a 256 bit integer can be computed as so:
let max_uint256 = Natural::from(2).pow(256) - 1;
Without support for primitives, it looks like this:
let max_uint256 = Natural::from(2).pow(256) - Natural::from(1);
Non-trivial overhead for a simple add/sub by 1 operation.
I see. If I picked a single primitive integer type, say i32, and implemented all operations between Natural, Integer, and Rational and that type, that would allow you to use literals. Just to clarify, by "overhead" you mean the number of characters you need for Natural::from(1), right? If you instead mean the time or memory used, that's already very low and adding i32 implementations wouldn't change that significantly.
I can make this change, but not for the next release, which already has a lot going into it.
In the meantime, there's a few things you can do to simplify your example code. You can use some constants:
use malachite::num::basic::traits::{One, Two};
let max_uint256 = Natural::TWO.pow(256) - Natural::ONE;
or the PowerOf2 trait:
use malachite::num::arithmetic::traits::PowerOf2;
use malachite::num::basic::traits::One;
let max_uint256 = Natural::power_of_2(256) - Natural::ONE;
or, most simply, the LowMask trait:
use malachite::num::logic::traits::LowMask;
let max_uint256 = Natural::low_mask(256);
Thanks, the use of the constant ONE is a good point and you're right that implementing for i32 is sufficient to cover literals.