[rust-dev] std::num::pow() is inadequate / language concepts
slabode at aim.com
Fri Jul 25 04:43:23 PDT 2014
On 07/24/2014 06:46 PM, Gregor Cramer wrote:
> 1. Overloading is not supported (even the archaic C++ is providing this).
I should note that Rust provides a limited form of overloading via the
trait-double dispatch trick:
fn pow(self, exp: uint) -> Res;
fn pow<Res, T: PowImpl<Res>>(t: T, exp: uint) -> Res
impl PowImpl<int> for int
fn pow(self, exp: uint) -> int
impl<'l> PowImpl<BigInt> for &'l BigInt
fn pow(self, exp: uint) -> BigInt
Note that this is not suitable for generic code, which is kind of an
under-appreciated problem. Currently Rust places running generic code
above writing efficient code, which is not a trade-off it should be
making imo. In my matrix library I opted for making my types useless for
generic code in the quest for efficiency, and I find it unfortunate that
I had to do that.
> 2. The footprint 'base: T' is not 100% suitable, for big integers the
> fn pow(base: &BigInt, mut exp: uint) -> BigInt
> would be more appropriate, because the argument 'base' needs not to be
> modified (or reassigned), and a call by reference (avoiding a superfluous
> memory allocation) is more efficient in this case.
Yes, I concur on most of these points and I've brought up some related
points before. The operator overloading technique used by Rust is
antithetical to efficient generic code. The core numeric traits and
functions are currently designed only with built-in types in mind,
causing BigInt (and others, e.g. matrices) to suffer. I don't know how
to fix these things, but perhaps auto-ref and ad-hoc operator
overloading (it works for Haskell, why not for Rust?) would be part of
the solution. Ultimately, I suspect that function overloading (the Rust
trait double-dispatch trick above may be sufficient with auto-ref) will
be of critical importance. This problem is very under-appreciated and I
hope this aspect of the language is not stabilized by 1.0.
If the relevant operator overload is removed from BigInt, then one
temporary solution will emerge: you won't be able to call this pow
function at all, and will be forced to call a specialized version. As
long as the core is designed for built-in types only, BigInt should stop
pretending to be one. I think this is what should be done in the interim.
More information about the Rust-dev