[rust-dev] std::num::pow() is inadequate / language concepts

SiegeLordEx 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:

trait PowImpl<Res>
{
	fn pow(self, exp: uint) -> Res;
}

fn pow<Res, T: PowImpl<Res>>(t: T, exp: uint) -> Res
{
     t.pow(exp)
}

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
> function
>
> definition
>
> 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.

-SL



More information about the Rust-dev mailing list